Nodejs websocket client, receive multiple messages - javascript

Building on my problem (Nodejs websockets client pending promise), it appears that promises cannot be used in the conventional way with websockets.
My scenario is:
a nodejs client to open a connection to websocket server
when a 'hello from server' is received from the server, nodejs client is to respond with a 'hello from client'
server will then stream multiple messages to client
server will end stream with 'goodbye client'
client disconnects
The most promising direction I've found is https://www.npmjs.com/package/websocket-as-promised however this only handles a finite number of responses using .then. My server will respond with a variable number of responses.

Related

How to connect HTML WebSocket to C++ Socket

I have an app where I am trying to connect to a C++ server which opens up a socket.
// Client side
var ws = new WebSocket('ws://<<IP:PORT>>');
In the server side, it is opening up a socket using
int sockfd = socket(domain, type, protocol)
(ref: https://www.geeksforgeeks.org/socket-programming-cc/)
Not aware of the c++ server implementation.
I was told that the server would start a WebSocket server to which my HTML app can connect.
But, the connection is not happening. I feel that the WebSocket on the client side is not same as socket on the server side and hence the connection is not establishing.
Please, someone, suggest what is wrong and how to make it right.
P.S. Please don't mind if it is a dumb question.
Since the server guys are not ready to change their implementation of the plain socket, as a workaround I created a C++ client which connects to the server using the plain socket. Then I am creating a WebSocket Server using NodeJs which executes the C++ client as a child process to get the data. So, my WebSocket client is now able to get the data from the main server through the NodeJs WebSocket interface server.
Cons:
A dependency of the C++ client.
Latency (since network speed is not a factor now, it works).

Can you make existing Tcp connection a Websocket to Client

I am in a situation where I am using a tcp connection on back end to stream data from SERVER A to SERVER B. SERVER A is running a client to talk to a database. SERVER B is running web server to handle requests from client. SEVER B has requirement to stream data from SERVER A to CLEINT via web socket.
i.e. A -tcp-> B -websocket-> CLIENT
Currently I am opening a web socket on SERVER B when the CLIENT requests page at /websocket. /websocket will return html page to establish connection websocket on SERVER B. Once the connection is established I am opening a new tcp connection to SERVER A while the websocket is open, and passing data from B's tcp connection to A, through websocket connection to client.
i.e.
CLIENT -> GET /websocket -> SERVER B -tcp-> SERVER A
SERVER A -data-> SERVER B -data> CLIENT
My understanding of TCP connetions and their protocol is fairly limited. From what I can gather, a web socket exists within a TCP connetion, but transfers data via different protocol (HTTP?). There is a thorough description of how they work in this video, though a lot of it is over my head. There is one section where she describes how a "key" string is passed from the client to the server and the server magically generates an "accept" string and sends response to client.
This may be a silly question but I wondering if there is some way I can forward that key from the CLIENT, through SERVER B to SERVER A, without creating a tcp connection from SERVER B to CLIENT. Goal here is to have the CLIENT create only one connection to SERVER A when /websocket is hit.
i.e.
CLIENT -websocketKey-> SERVER B -websocketKey-> SERVER A -websocketAccept-> SERVER B -websocketAccept-> CLIENT
Thanks for your help , and please be kind in your responses as I am inexperienced in this area.
What you are describing is a proxy or gateway function where server B works as an intermediary between server B and the client and handles the fact that server A and the client speak different protocols and that the client cannot connect directly to server A. This is perfectly doable.
Client makes webSocket connection to Server B.
Server B accepts that connection.
Server B connects to Server A and requests data over TCP (using some proprietary protocol).
Server B starts receiving data from Server A. For each meaningful "chunk" of data it receives from Server A, it sends that data over the webSocket to the client, making sure it is in a format that the client understands.
Client starts receiving chunks of data.
How you handle the conversion of data from whatever format it is in when it comes from Server B to whatever you want to send over the webSocket is entirely application-specific and up to you. It may be that you can just send the data raw as it is from Server A or it may be that you need to clean it up in some way to make it easier for the client to understand.
I do not understand what you are talking about with the webSocketKey. A webSocket connection uses a security key as part of establishing the connection, but that should be handled entirely for you with the various webSocket libraries on the client and on Server B. You don't have to participate in that at all. You aren't making a webSocket connection all the way from the client to Server A. You are making a webSocket connection from the client to Server B and then your normal TCP connection from server B to server A. server B is playing the part of a middleman fetching data from server A and then sending it over a different connection to the client. You have two separate connections:
webSocket Your TCP connection
(proprietary protocol)
client <--> server B server B <--> server A

Websocket Server connect to Django for forwarding Broadcasts

I really didn't know how to ask but, how would I setup a JavaScript SocketIO or Node socket server that would be able to accept messages from HTTP requests (Restful API)?Basically I have a Django back end, and want a SocketIO or Node server to run side by side, handling real time events fed to it through HTTP requests.
Is there anyway to send a HTTP request to the SocketIO or Node server that would the digest and send to broadcast to it's rooms? Or is this even realistic?
You can use Redis Pub/Sub along with your Django backend, Node server and and socket.io.
What you have to do is make your Django server listen to Http requests and publish real time events onto Redis. Also Start a Node.js server which would Subscribe to events published by your Django server on Redis. Then connect Socket.io to Node.js server to get events in real time on client side. Here is a tutorial

Using Socket.io client to connect to a different socket server

I have a simple server written in C. Its capable of receiving (and sending) messages via a specified socket. I'd like to use socket.io client to send messages to this server. I setup a simple html page and tried connecting via
var socket = io('http://my.server.ip:8080');
My server gets the connection but then socket.io gives this error repeatedly on the javascript console.
GET http://my.server.ip:8080/socket.io/?EIO=3&transport=polling&t=1431027762284-4 net::ERR_CONNECTION_RESET
I'm guessing my server should do a websocket 'handshake' to establish the connection. Is there a way to transmit a message in to a socket via JS with no handshake?
Please note my server does not use any standard, Its a rudimentary socket server that can receive and respond.
There are web socket server libraries you can use.
a plain socket does not work with web sockets.

Send message from Node.js Server to Client via function call

I want to send messages from my server to my client when a function is called. Using the code from this answer messages can be successfully sent from Server to Client every second.
I am building an application that runs node in the background, ideally I would like to be able to click a button that will call a function in the node server.js file which takes a parameter and sends that message to the client. The function in question would look like this
function sendToClient(message) {
clients[0].emit('foo', msg);
}
This would send the passed in message to the first client. How can I go about this?
In terminal, after you run node server.js is there a way to call a function from the server file using terminal, this could be a possible solution if so.
The best way to send messages from server to client right now is using webSockets. The basic concept is this:
Client A loads web page from server B.
Client A runs some javascript that creates a webSocket connection to server B.
Server B accepts that webSocket connection and the socket stays open for the duration of the life of the web page.
Server B registers event handlers to handle incoming messages from the web page.
Client A registers event handlers to handle incoming messages from the server.
At any point in time, the server can proactively send data to the client page and it will receive that data.
At any point in time, the client may sent data to the server and it will receive that data.
A popular node.js library that makes webSocket support pretty easy is socket.io. It has both client and server support so you can use the same library for both ends of the connection. The socket.io library supports the .emit() method mentioned in your question for sending a message over an active webSocket connection.
You don't directly call functions from client to server. Instead, you send a message that triggers the server to run some particular code or vice versa. This is cooperative programming where the remote end has to be coded to support what you're asking it to do so you can send it a message and some optional data to go with the message and then it can receive that message and data and execute some code with that.
So, suppose you wanted the server to tell the client anytime a temperature changed so that the client could display in their web page the updated temperature (I actually have a Raspberry Pi node.js server that does exactly this). In this case, the client web page establishes a webSocket connection to the server when the page loads. Meanwhile, the server has its own process that is monitoring temperature changes. When it sees that the temperature has changed some meaningful amount, it sends a temperature change message to each connected client with the new temperature data. The client receives that message and data and then uses that to update it's UI to show the new temperature value.
The transaction could go the other way too. The client could have a matrix of information that it wants the server to carry out some complicated calculation on. It would send a message to the server with the type of calculation indicated in the message type and then send the matrix as the data for the message. The server would receive that message, see that this is a request to do a particular type of calculation on some data, it would then call the appropriate server-side function and pass it the client data. When the result was finished on the server, it would send a message back to the client with the result. The client would receive that result and then do whatever it needed to with the calculated result.
Note, if the transactions are only from client to server with a response then coming back from the server, a webSocket is not needed for that type of transaction. That can be done with just an Ajax call. Client makes ajax call to the server, server formulates a response and returns the response. Where webSockets are most uniquely useful is if you want to initiate the communication from the server and send unsolicited data to the client at a time that the server decides. For that, you need some continuous connection between client and server which is what a webSocket is designed to be.
It appears there may be more to your question about how to communicate from a C# server to your node.js server so it can then notify the client. If this is the case, then since the node.js server is already a web server, I'd just add a route to the node.js server so you can simply do an http request from the C# server to the node.js server to pass some data to the node.js server which it can then use to notify the appropriate client via the above-described webSocket connection. Depending upon your security needs, you may want to implement some level of security so that the http request can only be sent locally from your C# server, not from the outside world to your node.js server.
In order to send a command to a client via the console there are two options, single process or multiprocess:
Single Process
When the command is run from console, temporary socket.io server starts listening on a port.
Once the client connects, send the message to the client.
Disconnect and stop the console app.
The reason this works is that socket.io clients are always trying to connect to the server. As long as the browser is open, they will try to connect. So even if the server only comes on for a few seconds, it should connect and receive messages. If the client is not running then simply create a timeout that will stop the console app and inform the user that it failed to broadcast the command.
While this approach is very easy, it's not robust nor efficient. For small projects this would work, but you'll have better luck with the next approach:
Multi-Process
This approach is much more reliable, expandable, and just better looking when you are talking about architecture. Here's the basic summary:
Spin up a stand-alone server that connects with clients.
Create a very similar console node app that will send a message to the server to forward on to clients.
Console app completes but the main server stays up and running.
This technique is just interprocess communication. Luckily you already have Socket.IO on the primary server, so your console app just needs to be another socket.io client. Check out this answer on how to implement that.
The downside to this is that you must secure that socket communication. Maybe you can enforce it to just allow localhost connections, that way you need access to the server to send the run command message (you absolutely don't want web clients executing code on other web clients).
Overall it comes down to the needs of your project. If this is a quick little experiment you want to try out, then just do it single process. But if will be hosting an express server (other webservers are available) and need to be running anyways, then multi-process is the way to go!
Example
I've created a simple example of this process using only Socket.io. Instructions to run it all are in the readme.
Implementations
In order to have C# (app) -> Node.js (server) -> Browser (client) communication then I would do one of the following:
Use redis as a message queue (add items to the queue with the app, consume with the server, which sends commands to client).
Live on the wild side and merge your NodeJS and C# runtimes with Edge.js. If you can run NodeJS from C# you will be able to send messages from your app to the server (messages are then handled by the server, just like any other socket.io client-server model).
Easier, but still kinda hacky, use System.Diagnostics.Process to start a console tool explained in the Multi-Process section. This would simply run the process with arbitrary parameters. Not very robust but worth considering, simple means harder to break (And again, messages are then handled by the server, just like any other socket.io client-server model).
I would create a route for sending the message and send message from post parameter. From CLI you can use curl or from anywhere really:
app.get('/create', function(req, res) {
if( data.type && data.content && data.listeners){
notify( data );
}
});
var notify = function( notification ){
ns_mynamespace.in(notification.listeners.users)
.emit("notification", {
id: notification.id,
title: 'hello', text: notification.content });
}
}

Categories

Resources