Creating a chat with nodejs ws (einaros) - node.js

Yesterday I started using this module. I'm trying to make a chat for do something with websockets.
I have the problem, that I don't know how to pass the message that sends a client to the server for then show it for all users. In the server side I have this code:
var ipaddress = 'localhost';
var port = 8080;
var WebSocketServer = require('ws').Server
, ws = new WebSocketServer({host:ipaddress, port:port});
ws.on('connection', function(ws) {
console.log('New connection');
ws.on('message', function(message) {
ws.send(message);
});
});
console.log('Listening to ' + ipaddress + ':' + port + ' ...');
And in the client side this other code:
jQuery(document).ready(function($) {
var content = $('#screen');
var message = $('input[type="text"]').val();
var ws = new WebSocket('ws://localhost:8080');
ws.onopen = function() {
console.log('Connected');
};
$('input[type="button"]').click(function() {
ws.send(message);
});
ws.onmessage = function(msg) {
console.log('Received message from server: ' + msg.data);
addMessage(msg.data);
}
function addMessage(message) {
content.prepend('<p><span>' + message + '</span></p>');
}
});

It's explained here:
var WebSocketServer = require('ws').Server
, wss = new WebSocketServer({host:ipaddress, port:port});
wss.broadcast = function(data) {
for (var i in this.clients)
this.clients[i].send(data);
};
// use like this:
wss.on('connection', function(ws) {
ws.on('message', function(message) {
wss.broadcast(message);
});
});

var WebSocketServer = require('ws').Server
var webserver = new WebSocketServer({ port:3000 });
webserver.on("message",function(message) {
webserver.clients.forEach(function(client) {
client.send(message);
});
}):

Related

Sockets.io issue: WebSocket is closed before the connection is established

I am currently building a nodejs webrtc video conference, hosted on azure. The program works perfectly fine locally, but when hosted there seems to be an issue with websockets. The client side error is below:
WebSocket connection to '<URL>' failed: WebSocket is closed before the connection is established.
index.js:83 WebSocket connection to 'wss://etuition.azurewebsites.net:8080/socket.io/?EIO=3&transport=websocket' failed: WebSocket is closed before the connection is established.
I have seen other stack overflow posts claiming that this is due to SSL, but site is currently running on HTTPS so this should not be a problem for me. Is it possible that the ws server is insecure even though my http server is secure?
Any other advice on what could be the problem will be greatly appreciated.
Below I have included my server.js code.
Please ask if any more information is needed:
/**
* Server module.
*
*
*/
'use strict';
var environment = process.env.RTC_ENV || 'local';
var debug = require('debug')('expressapp:server');
var express = require('express');
var cors = require('cors');
const http = require('http');
var logger = require('./logger').logger(environment);
var serverPort = normalizePort(process.env.PORT || '8080');
//var serverPort = normalizePort(process.env.PORT || '8080');
function normalizePort(val) {
var port = parseInt(val, 10);
if (isNaN(port)) {
// named pipe
return val;
}
if (port >= 0) {
// port number
return port;
}
return false;
}
//var serverPort = process.env.RTC_PORT || 31000
var serverIpAddress = process.env.RTC_IP || 'localhost'
var socketIoServer = 'etuition.azurewebsites.net' + ':' + serverPort;
////////////////////////////////////////////////
// SETUP SERVER
////////////////////////////////////////////////
var app = express();
app.set('port', serverPort);
function redirectSec(req, res, next) {
if (req.headers['x-forwarded-proto'] == 'http') {
var redirect = 'https://' + req.headers.host + req.path;
console.log('Redirect to:' + redirect);
res.redirect(redirect);
} else {
return next();
}
}
app.use(redirectSec);
require('./router')(app, socketIoServer, environment);
// Static content (css, js, .png, etc) is placed in /public
app.use(express.static(__dirname + '/public'));
app.use(cors());
// Location of our views
app.set('views', __dirname + '/views');
// Use ejs as our rendering engine
app.set('view engine', 'ejs');
// Tell Server that we are actually rendering HTML files through EJS.
app.engine('html', require('ejs').renderFile);
const server = http.createServer(app);
server.listen(serverPort);
server.on('listening', onListening);
function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
logger.info("Socket IO Address:" + socketIoServer);
logger.info("Server IP Address:" + serverIpAddress);
logger.info('Server running on port ' + serverPort);
}
var io = require('socket.io').listen(server, { log: false, origins: '*:*' });
////////////////////////////////////////////////
// EVENT HANDLERS
////////////////////////////////////////////////
io.sockets.on('connection', function (socket) {
function log() {
var array = [">>> Message from server: "];
for (var i = 0; i < arguments.length; i++) {
array.push(arguments[i]);
}
socket.emit('log', array);
}
socket.on('message', function (message) {
log('Got message: ', message);
logger.info("message: ", message);
socket.broadcast.to(socket.room).emit('message', message);
});
socket.on('create or join', function (message) {
var room = message.room;
socket.room = room;
var participantID = message.from;
configNameSpaceChannel(participantID);
io.of('/').in(room).clients(function (error, clients) {
var numClients = clients.length;
log('Room ' + room + ' has ' + numClients + ' client(s)');
log('Request to create or join room', room);
if (numClients == 0) {
logger.info(participantID + " joined first. Creates room " + room);
socket.join(room);
socket.emit('created', room);
} else {
logger.info(participantID + " joins room " + room);
io.sockets.in(room).emit('join', room);
socket.join(room);
socket.emit('joined', room);
}
})
});
// Setup a communication channel (namespace) to communicate with a given participant (participantID)
function configNameSpaceChannel(room) {
var nsp = '/' + room;
var socketNamespace = io.of(nsp);
logger.info('ConfigNameSpaceChannel:' + nsp);
socketNamespace.on('connection', function (socket) {
socket.on('message', function (message) {
// Send message to everyone BUT sender
socket.broadcast.emit('message', message);
});
});
return socketNamespace;
}
});

Nodejs , Redis,Sockets

I have a nodejs app which reads data from redis and I am unable to push it into socket. In the c.write(message) part, if I hardcode(example c.write('hello') ,the messages are being put to the socket but when i put it as c.write(message), nothing is going to the socket. Thanks in advance,
var net = require('net');
var split = require('split');
var Redis = require('ioredis');
var redis = new Redis();
var server = net.createServer(function(c) {
console.log('client connected');
c.on('end', () => {
console.log('client disconnected');
});
redis.subscribe('test-channel');
redis.on('message', function(channel, message) {
console.log(message);
c.write(message);
c.pipe(c);
});
});
server.on('error', (err) => {
throw err;
});
server.listen(3005, 'localhost', () => {
console.log('server bound');
});
I have got the answer.
Just add below lines to your code :
var message_redis = message+'\r'+'\n';
c.write(message_redis);

node server not working with express-ws

I have a node WebServer capable of communicating with Browser(say browserInstance) and linux terminal(say ProxyInstance) via Websockets. The job of the webserver is to handover the data from terminal to WebBrowser and vice-verse. Please find the server.js code below:
var express = require('express');
var expressWs = require('express-ws');
var expressWs = expressWs(express());
var app = expressWs.app;
var appForpage = express();
var browserInstance;
var ProxyInstance;
var browserCounter = 0;
var ProxyCounter = 0;
app.ws('/fromBrowser', function(ws, req, next) {
console.log("~~~~~~~~~~~~BROWSER");
if(browserCounter == 1){
ws.on('message', function(msg) {
console.log("Messagae from Browser :", msg);
ProxyInstance.send(msg);
});
}else{
browserInstance = ws;
ws.on('message', function(msg) {
console.log("Message from Browser :", msg);
ProxyInstance.send(msg);
});
browserCounter = 1;
}
ws.on('close', function(){
console.log("Ws Connection closed");
});
//next();
});
app.ws('/fromProxy', function(ws, req, next) {
console.log("~~~~~~~~~~~~PROXY");
if(ProxyCounter == 0){
ProxyInstance = ws;
ProxyCounter = 1;
}else if(browserCounter == 1){
ws.on('message', function(msg) {
console.log("Message from Proxy: ", msg);
browserInstance.send(msg);
});
}
ws.on('close', function(){
console.log("Ws Connection closed");
});
//next();
});
appForpage.use(express.static(__dirname + '/public/')); // index.html resides in public directory
appForpage.listen(5000)
app.listen(3000)
First I am creating ws connection from proxy to webserver(/fromProxy) and then from browser(/fromBrowser). The connection was successfully created. When i try to send data from Browser to proxy via Webserver, it works fine. In return to the 1st message at proxy end when tries to communicate Browser via WebServer, this one failed. I haven't received any message from Proxy. I need to run the respective ends in the same order(Proxy first and then Browser..).
I am just beginner to node. I haven't find any example over internet for my case. What am I missing here ?
That's really silly :( .I haven't registered my messsage callback from proxy. Please find the working code below.
var express = require('express');
var expressWs = require('express-ws');
var expressWs = expressWs(express());
var app = expressWs.app;
var appForpage = express();
var browserInstance;
var ProxyInstance;
var browserCounter = 0;
var ProxyCounter = 0;
app.ws('/fromBrowser', function(ws, req, next) {
console.log("~~~~~~~~~~~~BROWSER");
if(browserCounter == 1){
ws.on('message', function(msg) {
console.log("Messagae from Browser :", msg);
ProxyInstance.send(msg);
});
}else{
browserInstance = ws;
ws.on('message', function(msg) {
console.log("Message from Browser :", msg);
ProxyInstance.send(msg);
});
browserCounter = 1;
}
ws.on('close', function(){
console.log("Ws Connection closed");
});
//next();
});
app.ws('/fromProxy', function(ws, req, next) {
console.log("~~~~~~~~~~~~PROXY");
if(ProxyCounter == 0){
ProxyInstance = ws;
ProxyCounter = 1;
}
/*This is the place where i went wrong. damnn..*/
ws.on('message', function(msg) {
console.log("Message from Proxy: ", msg);
browserInstance.send(msg);
});
ws.on('close', function(){
console.log("Ws Connection closed");
});
//next();
});
appForpage.use(express.static(__dirname + '/public/')); // index.html resides in public directory
appForpage.listen(5000)
app.listen(3000)

socket.io with node cluster only long poll works

Using socket.io and nodeJS cluster, looks like Websocket protocol fails and it falls back to long polling, any idea why it isnt using websocket?
This is the only error in console
WebSocket connection to
'ws://localhost:5050/socket.io/?EIO=3&transport=websocket&sid=82qh7nBXGusxyelJAAAG'
failed: Connection closed before receiving a handshake response
Here is my node application
if (cluster.isMaster) {
// we create a HTTP server, but we do not use listen
// that way, we have a socket.io server that doesn't accept connections
var server = require('http').createServer();
var io = require('socket.io').listen(server);
var redis = require('socket.io-redis');
var fs = require('fs');
io.adapter(redis({host: '127.0.0.1', port: 6379}));
var i = 0;
setInterval(function () {
// all workers will receive this in Redis, and emit
io.sockets.in('EURUSD').emit('message', 'EURUSD ' + i++);
io.sockets.in('GBPUSD').emit('message', 'GBPUSD ' + i++);
}, 1000);
for (var i = 0; i < os.cpus().length; i++) {
cluster.fork();
}
cluster.on('online', function (worker) {
console.log("New Worker with ID ", worker.id);
});
cluster.on('exit', function (worker, code, signal) {
console.log('worker ' + worker.process.pid + ' died');
});
}
if (cluster.isWorker) {
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
server.listen(config.port);
var io = require('socket.io').listen(server);
var redis = require('socket.io-redis');
io.adapter(redis({host: '127.0.0.1', port: 6379}));
io.sockets.on('connection', function (socket) {
console.log('connected to worker id ', cluster.worker.id);
socket.on('join', function (room) {
socket.join(room);
});
});
app.get("/", function (req, res) {
res.sendFile('views/index.html', {root: __dirname});
});
}
Client code
var socket = io();
socket.on('message', function (data) {
var item = $('<li>' + data + '</li>');
$('ul').prepend(item);
});
socket.emit("join", "GBPUSD");
For those who may face similar issue, it turned out that I have the following line twice
var io = require('socket.io')(server);
Removing one, solved the issue.

How to create a simple socket in node.js?

I'm trying to create a dummy socket for use in some of my tests
var net = require("net");
var s = new net.Socket();
s.on("data", function(data) {
console.log("data received:", data);
});
s.write("hello!");
Getting this error
Error: This socket is closed.
I've also tried creating the socket with
var s = new net.Socket({allowHalfOpen: true});
What am I doing wrong?
For reference, the complete test looks like this
it("should say hello on connect", function(done) {
var socket = new net.Socket();
var client = Client.createClient({socket: socket});
socket.on("data", function(data){
assert.equal("hello", data);
done();
});
client.connect();
// writes "hello" to the socket
});
I don't think the server is put into listening state. This what I use..
// server
require('net').createServer(function (socket) {
console.log("connected");
socket.on('data', function (data) {
console.log(data.toString());
});
})
.listen(8080);
// client
var s = require('net').Socket();
s.connect(8080);
s.write('Hello');
s.end();
Client only..
var s = require('net').Socket();
s.connect(80, 'google.com');
s.write('GET http://www.google.com/ HTTP/1.1\n\n');
s.on('data', function(d){
console.log(d.toString());
});
s.end();
Try this.
The production code app.js:
var net = require("net");
function createSocket(socket){
var s = socket || new net.Socket();
s.write("hello!");
}
exports.createSocket = createSocket;
The test code: test.js: (Mocha)
var sinon = require('sinon'),
assert = require('assert'),
net = require('net'),
prod_code=require('./app.js')
describe('Example Stubbing net.Socket', function () {
it("should say hello on connect", function (done) {
var socket = new net.Socket();
var stub = sinon.stub(socket, 'write', function (data, encoding, cb) {
console.log(data);
assert.equal("hello!", data);
done();
});
stub.on = socket.on;
prod_code.createSocket(socket);
});
});
We can create socket server using net npm module and listen from anywhere. after creating socket server we can check using telnet(client socket) to interact server.
server.js
'use strict';
const net = require('net');
const MongoClient= require('mongodb').MongoClient;
const PORT = 5000;
const ADDRESS = '127.0.0.1';
const url = 'mongodb://localhost:27017/gprs';
let server = net.createServer(onClientConnected);
server.listen(PORT, ADDRESS);
function onClientConnected(socket) {
console.log(`New client: ${socket.remoteAddress}:${socket.remotePort}`);
socket.destroy();
}
console.log(`Server started at: ${ADDRESS}:${PORT}`);
function onClientConnected(socket) {
let clientName = `${socket.remoteAddress}:${socket.remotePort}`;
console.log(`${clientName} connected.`);
socket.on('data', (data) => {
let m = data.toString().replace(/[\n\r]*$/, '');
var d = {msg:{info:m}};
insertData(d);
console.log(`${clientName} said: ${m}`);
socket.write(`We got your message (${m}). Thanks!\n`);
});
socket.on('end', () => {
console.log(`${clientName} disconnected.`);
});
}
function insertData(data){
console.log(data,'data');
MongoClient.connect(url, function(err, db){
console.log(data);
db.collection('gprs').save(data.msg , (err,result)=>{
if(err){
console.log("not inserted");
}else {
console.log("inserted");
}
});
});
}
using telnet:
$ telnet localhost 5000
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
hi
We got your message (hi). Thanks!
you need to connect your socket before you can write to it:
var PORT = 41443;
var net = require("net");
var s = new net.Socket();
s.on("data", function(data) {
console.log("data received:", data);
});
s.connect(PORT, function(){
s.write("hello!");
});
It will useful code for websocket
'use strict';
const express = require('express');
const { Server } = require('ws');
const bodyParser = require('body-parser');
const cors = require('cors');
const PORT = process.env.PORT || 5555;
const INDEX = '/public/index.html';
const router = express.Router();
var urlencodedParser = bodyParser.urlencoded({ extended: false });
router.get('/', function(req, res) {
res.sendFile(INDEX, { root: __dirname });
});
const server = express()
.use(router)
.use(bodyParser.json())
.use(cors)
.listen(PORT, () => {
console.log(`Listening on ${PORT}`)
});
const wss = new Server({ server });
wss.on('connection', (ws) => {
ws.on('message', message => {
var current = new Date();
console.log('Received '+ current.toLocaleString()+': '+ message);
wss.clients.forEach(function(client) {
client.send(message);
var getData = JSON.parse(message);
var newclip = getData.clipboard;
var newuser = getData.user;
console.log("User ID : "+ newuser);
console.log("\nUser clip : "+ newclip);
});
});
});

Resources