I am trying to create a system where I have a desktop client created in VB, and a browser based client, that can send messages to each other. I am using a Node.js server to handle the connections and messages.
This is the code of my Node.js server:
net = require('net')
// Supports multiple client chat application
// Keep a pool of sockets ready for everyone
// Avoid dead sockets by responding to the 'end' event
var sockets = [];
// Create a TCP socket listener
var s = net.Server(function (socket) {
// Add the new client socket connection to the array of
// sockets
sockets.push(socket);
// 'data' is an event that means that a message was just sent by the
// client application
socket.on('data', function (msg_sent) {
// Loop through all of our sockets and send the data
for (var i = 0; i < sockets.length; i++) {
// Don't send the data back to the original sender
if (sockets[i] == socket) // don't send the message to yourself
continue;
// Write the msg sent by chat client
sockets[i].write(msg_sent);
}
});
// Use splice to get rid of the socket that is ending.
// The 'end' event means tcp client has disconnected.
socket.on('end', function () {
var i = sockets.indexOf(socket);
sockets.splice(i, 1);
});
});
s.listen(8000);
console.log('System waiting at http://localhost:8000');
With this sever, I am able to send messages between two desktop clients successfully.
However, because I am using net and not HTTP I cannot get the browser based client to connect.
How can I get both the clients to connect? I would really appreciate any help/suggestions/directions. I have been searching everywhere for about 4 days now! TIA!
You could use http or express for browser based client. could check socket.io also which works on http port.
I would try to help more if know type of the desktop client you are using.
Related
I have a ws.on('connection') event on my server which sends a JSON object to each connected client on their first connection.
However because of this bit:
// Sending the payload to all clients.
wss.clients.forEach((client) => {
// Prepare for transmission.
let transmission = JSON.stringify(SocketObject.query());
// Debug
console.log('[server:onConnection:init]');
// Send the transmission.
client.send(transmission);
});
Every time a client connects, the JSON object is transmitted to every client again and again. Is it possible to limit this reply to only the client that is getting connected initially?
It was my mistake, so when wrapped like this:
wss.on('connection', (ws) => {
console.log('[server:onConnection]');
ws.send('FIRST_RESPONSE');
... it does exactly what I need it to do. Meaning it only sends the message to the connected client. I don't know why I had the forEach(client) bit in there.
My problem is that the current solution I have for sending a specific socket using the library "ws" with node.js is not good enough.
The reason is because if I connect with multiple tabs to the websocket server with the same userid which is defined on the client-side, it will only refer to the latest connection with the userid specified.
This is my code:
// Server libraries and configuration
var server = require("ws").Server;
var s = new server({ port: 5001});
// An array which I keep all websockets clients
var search = {};
s.on("connection", function(ws, req) {
ws.on("message", function(message){
// Here the server process the user information given from the client
message = JSON.parse(message);
if(message.type == "userinfo"){
ws.personName = message.data;
ws.id = message.id;
// Defining variable pointing to the unique socket
search[ws.id] = ws;
return;
}
})
})
As you can see, each time a socket with same id connects, it will refer to the latest one.
Example If you did not understand:
Client connect to server with ID: 1337
search[1337] defined as --> websocket 1
A new connection with same ID: 1337
search[1337] becomes instead a variable refering to websocket 2 instead
Websockets provide a means to create a low-latency network "socket" between a browser and a server.
Note that the client here is the browser, not a tab on a browser.
If you need to manage multiple user sessions between the browser and server, you'll need to write code to do it yourself.
I'm trying to develop a video-chat application using webRTC and WebSockets for signaling.
My problem is that I don't know exactly what is the process of creating RTCPeerConnection and connect both peers(2 browsers) through webSocket(Locally at least).
I know how to communicate clients though WebSockets, but not with the RTCPeerConnection API, you know any tutorial step-by-step explaining the process?(Offer SDP, answers, ICE, ...) and, on the other hand, how looks the server code to managing these clients through RTCPeerConnection?
Here is my Node.js code for the server
"use strict";
// Optional. You will see this name in eg. 'ps' or 'top' command
process.title = 'node-webrtc';
// Port where we'll run the websocket server
var webSocketsServerPort = 1337;
// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');
/* ---------------------------------
GLOBAL VARIABLES
----------------------------------*/
// latest 100 messages
//var history = [ ];
// list of currently connected clients (users)
var clients = [ ];
/* ---------------------------------
HTTP SERVER
----------------------------------*/
var server = http.createServer(function(request, response) {
// Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
});
/* ---------------------------------
WEBSOCKET SERVER
----------------------------------*/
var wsServer = new webSocketServer({
// WebSocket server is tied to a HTTP server. WebSocket request is just
// an enhanced HTTP request. For more info http://tools.ietf.org/html/rfc6455#page-6
httpServer: server
});
// This callback function is called every time someone
// tries to connect to the WebSocket server
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
// accept connection - you should check 'request.origin' to make sure that
// client is connecting from your website
// (http://en.wikipedia.org/wiki/Same_origin_policy)
var connection = request.accept(null, request.origin);
// we need to know client index to remove them on 'close' event
var index = clients.push(connection) - 1;
console.log((new Date()) + ' Connection accepted.');
// user sent some message
connection.on('message', function(message) {
for (var i=0; i < clients.length; i++) {
clients[i].sendUTF(message);
}
});
// user disconnected
connection.on('close', function(conn) {
console.log((new Date()) + " Peer " + conn.remoteAddress + " disconnected.");
// remove user from the list of connected clients
clients.splice(index, 1);
});
});
You might want to have a look at the codelab I did for Google I/O: bitbucket.org/webrtc/codelab.
Step 5 shows how to set up a signaling server using socket.io, and Step 6 puts this together with RTCPeerConnection to make a simple video chat app.
You might also want to have a look at easyRTC (full stack) and Signalmaster (signaling server created for SimpleWebRTC).
The 'canonical' WebRTC video chat example at apprtc.appspot.com uses XHR and the Google App Engine Channel API for signaling.
Have you looked at or come across WebRTC.io? It is an opensource GitHub project that utilizes Node.js and websockets to do the exact thing you are talking about. I, not being much of a javascript person, was able to figure out what it was doing within a week. It isn't a step by step instruction, but anyone with javascript experience would be able to figure out the function call order.
There are two bits to the code: the server side and the client side. The server side is run with Node.js, and serves up the client side code to the browser. If I remember correctly, since the two projects are separate, if you want to combine them you will have to copy the webrtcio.js file from the client side and paste it into the server side folder. Although, I think if you clone the github repository right, you might not have to worry about that.
I'm using the ws library for WebSockets in Node.js and
I'm trying this example from the library examples:
var sys = require("sys"),
ws = require("./ws");
ws.createServer(function (websocket) {
websocket.addListener("connect", function (resource) {
// emitted after handshake
sys.debug("connect: " + resource);
// server closes connection after 10s, will also get "close" event
setTimeout(websocket.end, 10 * 1000);
}).addListener("data", function (data) {
// handle incoming data
sys.debug(data);
// send data to client
websocket.write("Thanks!");
}).addListener("close", function () {
// emitted when server or client closes connection
sys.debug("close");
});
}).listen(8080);
All OK. It works, but running 3 clients, for instance, and sending "Hello!" from one will make the server only reply "Thanks!" to the client which sent the message, not to all.
How can I broadcast "Thanks!" to all connected clients when someone sends "Hello!"?
Thanks!
If you want to send out to all clients, you have to keep track of them. Here is a sample:
var sys = require("sys"),
ws = require("./ws");
// # Keep track of all our clients
var clients = [];
ws.createServer(function (websocket) {
websocket.addListener("connect", function (resource) {
// emitted after handshake
sys.debug("connect: " + resource);
// # Add to our list of clients
clients.push(websocket);
// server closes connection after 10s, will also get "close" event
// setTimeout(websocket.end, 10 * 1000);
}).addListener("data", function (data) {
// handle incoming data
sys.debug(data);
// send data to client
// # Write out to all our clients
for(var i = 0; i < clients.length; i++) {
clients[i].write("Thanks!");
}
}).addListener("close", function () {
// emitted when server or client closes connection
sys.debug("close");
for(var i = 0; i < clients.length; i++) {
// # Remove from our connections list so we don't send
// # to a dead socket
if(clients[i] == websocket) {
clients.splice(i);
break;
}
}
});
}).listen(8080);
I was able to get it to broadcast to all clients, but it's not heavily tested for all cases. The general concept should get you started though.
EDIT: By the way I'm not sure what the 10 second close is for so I've commented it out. It's rather useless if you're trying to broadcast to all clients since they'll just keep getting disconnected.
I would recommend you to use socket.io. It has example web-chat functionality out of the box and also provides abstraction layer from the socket technology on client (WebSockets are supported by Safari, Chrome, Opera and Firefox, but disabled in Firefox and Opera now due to security vulnerabilities in ws-protocol).
I am using node.js building a TCP server, just like the example in the doc. The server establishes persistent connections and handle client requests. But I also need to send data to any specified connection, which means this action is not client driven. How to do that?
Your server could maintain a data structure of active connections by adding on the server "connection" event and removing on the stream "close" event. Then you can pick the desired connection from that data structure and write data to it whenever you want.
Here is a simple example of a time server that sends the current time to all connected clients every second:
var net = require('net')
, clients = {}; // Contains all active clients at any time.
net.createServer().on('connection', function(sock) {
clients[sock.fd] = sock; // Add the client, keyed by fd.
sock.on('close', function() {
delete clients[sock.fd]; // Remove the client.
});
}).listen(5555, 'localhost');
setInterval(function() { // Write the time to all clients every second.
var i, sock;
for (i in clients) {
sock = clients[i];
if (sock.writable) { // In case it closed while we are iterating.
sock.write(new Date().toString() + "\n");
}
}
}, 1000);