Onur Çevik Onur Çevik - 2 months ago 10
C# Question

Communicating with Node.js server code on Compute Engine using socket.io and C# client

I currently have a Compute Engine and App Engine working and a C# client application.
My goal is to connect my C# client app with google cloud and work real-time with requests and websocket.

For that purpose, after reading lots of documentations and guides, I decided to go with this logic:


  • Send requests to App Engine,

  • listen App Engine with Compute Engine and then

  • send response to C# app with Compute Engine, using websocket connection.



And for that, I tried using
socket.io
without any luck.

Issue here is my
mydomain.appspot.com
url is working fine, at least it shows a text without any change.

I get
Listening port xxxx
on my terminal, yet no changes occur.

I feel like I'm listening to something but not actually connected to it so code under
.connect
doesn't run.


  • What should I do to work this out?

  • Am I misunderstanding the concept?

  • I added a firewall rule on port 65080, which is the one I'm using.



I'm getting
Port is in use
error (Exit status code 8 error, but I looked it up and it means that) when I listen to whatever port, yet when I show active processes on that port, there are none.

Are there any additional configurations should I make on the Google Cloud part, other than the ones in official Bookshelf tutorial?

Server Code

var io = require('socket.io').listen(65080);

io.sockets.on('connection', function (socket) {
var address = socket.handshake.address;
console.log('New connection from ' + address.address + ':' + address.port);

io.sockets.emit('this', { will: 'be received by everyone'});

socket.on('private message', function (msg) {
console.log('New Chat Message ', msg);
io.sockets.emit('txt',msg);
});

socket.on('disconnect', function () {
io.sockets.emit('User Disconnected');
});

socket.on('newuser', function (name) {
console.log(name,' Is Now Connected!');
io.sockets.emit('txnpm start
t',name + ' is now online');
});

socket.on('exit', function (name) {
console.log(name,' Has Been Disconnected!');
io.sockets.emit('txt',name + ' is now offline');
});
});


Client Code

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
user = "x";
MyForm = new Form1();
temp = new Form2();
Application.Run(temp);
try
{
socket = new Client(ip.ToString());
socket.On("txt", (data) =>
{
//MessageBox.Show(data.RawMessage);
String msg = data.Json.Args[0].ToString();
Console.Write(msg);
MyForm.update(msg);
//MessageBox.Show(msg, "Received Data");
});
socket.Connect();
}
catch (Exception e)
{
MessageBox.Show(e.ToString(),"Something Went Wrong!!");
Application.Exit();
}
if (socket.ReadyState.ToString() == "Connecting")
{
userset();
Application.Run(MyForm);
}
else
{
MessageBox.Show("Failed To Connect To Server!", "Error!");
Application.Exit();
}


&&

using (var ws = new WebSocketSharp.WebSocket("ws://104.197.217.126:65080/"))
{
ws.OnMessage += (sender, e) =>
MessageBox.Show(e.Data);

ws.Connect();
}


EDIT:

Also tried a different approach on client side by following the client Android code provided by socket.io, just to make sure if the issue was with my C# client code. Still no result, same situation persists.

Android Client Code

Socket mSocket;
Activity activity;
public void connect(Activity a){
activity=a;

try {
mSocket = IO.socket("http://104.197.217.126:65080");
} catch (URISyntaxException e) {}

mSocket.on("new message", onNewMessage);
mSocket.connect();

// mSocket.emit("new message", "sadasdasd");
}

private Emitter.Listener onNewMessage = new Emitter.Listener() {

@Override
public void call(final Object... args) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
JSONObject data = (JSONObject) args[0];
String username;
String message;
try {
username = data.getString("username");
message = data.getString("message");
} catch (JSONException e) {
return;
}
// add the message to view
Toast.makeText(activity,username+"-"+message,Toast.LENGTH_LONG);
}
});
}
};

Answer

In conclusion, these are the steps I took:

  • Created a Compute Engine instance, installed node and other modules needed
  • Used the code I added to my question on the server side. For this, I first added my Node.js project to GitHub, then deployed it to my Compute Engine instance by simply connecting with SSH and using git clone http://github.com/username/repname.git
  • Then, in my projects directory, I started the .js file by using "node app.js" and it went into idle state, waiting for connections. This is all for the server side.
  • For the client side, I was using wrong libraries. I needed to use the socket.io client library to interact with my socket.io server app. So I used this library for my C# client app, but you can use other socket.io libraries for different languages.
  • My code for client app looks like this:

     var socket = IO.Socket("http://104.198.214.221:65080"); 
     // this ip has to be your instance's external IP, left to the SSH button on your Compute Engine instances page.
    
        socket.On(Socket.EVENT_CONNECT, () =>
        {
            socket.Emit("private message", "Hello. I'm connected!");
    
        });
    
        socket.On("private message", (data) =>
        {
    
            MessageBox.Show(data.ToString());
            socket.Disconnect();
        });
    
  • Bam! As my server code was running on instance computer, I got the "New Connection from: bla:bla" message as soon as the client app connection function called, and then received the "private message" event emit also.

It was a rookie mistake on my side. First thing to make sure is that you are using the socket.io client libraries, otherwise it won't work. And second, you need to connect to your IP and port using http://, not ws:// or wss://.

Hope this helps someone in future who is struggling with such simple problem. Thanks to everyone else who did their best to help despite my lack of information.

Comments