How can I have faye-websockets code running in the browser? - javascript

I'm new with node.js/express and all and I want to be able to notify any clients in browser about a new message received from some algorithm in the back-end. The publisher algorithm connect to the websocket and writes the message.
As far as I've looked there were examples which recommended websockets but I haven't been able to run that code in browser only in console.
Example client code:
var WebSocket = require('faye-websocket');
var ws = new WebSocket.Client('ws://localhost:1234');
var http = require('http');
var port = process.env.PORT || 1235;
var server = http.createServer()
.listen(port);
// receive a message from the server
ws.on('message', function(event) {
alert(JSON.parse(event.data));
});
Thank you

Found the answer after some trial/error iterations.
The algorithm now does a POST to an URL which in turn triggers a write to sockets for all connected clients via socket.io.
Client code:
var socket = io('http://localhost:7777');
socket.on('message', function (msg) {
document.body.insertAdjacentHTML( 'beforeend', '<div id="myID">'+msg+'</div>' );
});
And on the server, when client connects I retain it's socket into an array so I can write to each one:
Server code:
io.on('connection', function(socket){
console.log('a user connected: '+socket.id);
var id = clientCount++;
clientSockets[id] = socket;
socket.on('disconnect', function(){
console.log('user disconnected');
delete clientSockets[id];
socket = null
});
});
app.post('/alerts', function(req, res) {
req.accepts(['json', 'application']);
console.log("Algo did a POST on /alerts!");
// send the message to all clients
//console.log(req.body);
for(var i in clientSockets) {
clientSockets[i].send(JSON.stringify(req.body));
}
res.send(200);
});
In conclusion, I'm not using faye-websockets but instead socket.io

Related

getting an error when trying to use socket.io

I am currently working with socket.io swift client. Running on Iphone SE. this is the swift code
let socket = SocketIOClient(socketURL: URL(string: "http://example.com:4000")!, config: [.log(true), .forcePolling(true)]);
socket.connect();
socket.on("connect") {data, ack in
print("socket is connected");
socket.emit("getData", ["data": 3]);
}
And on the server:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('getData', function(result){
console.log(result);
});
});
app.listen(4000, function () {
console.log(' on at 4000!');
});
...And on the Xcode console, I get
2016-09-29 16:38:33.871895 proj[3070:1019256] LOG SocketEngine: Handshaking
2016-09-29 16:38:33.872301 proj[3070:1019256] LOG SocketEnginePolling: Doing polling request
2016-09-29 16:38:34.004312 proj[3070:1019256] LOG SocketEnginePolling: Got polling response
2016-09-29 16:38:34.004874 proj[3070:1019283] LOG SocketEngine: Got message: Cannot GET /socket.io/?transport=polling&b64=1
2016-09-29 16:38:34.005283 proj[3070:1019283] ERROR SocketIOClient: Got unknown error from server Cannot GET /socket.io/?transport=polling&b64=1
Which demonstrates a connection is made and the server is successfully found, but something else is wrong.
Would appreciate any help.
(Sidenote: If you don't need support for old browsers (or any browsers for that matter, since your client is a native mobile app) then you may consider using WebSocket which is an open standard. Socket.io is usually used to have a WebSocket-like functionality on browsers that don't support WebSocket. WebSocket on the other hand is an open standard, has a wide support (not only in browsers) and it has a better performance. See this answer for more details.)
Now, since you are already using Socket.io then here is how you can diagnose the problem. I would try to connect from a browser, which is a main way to connect with Socket.io, and see if that works. If it doesn't then it would mean that there's a problem in your server code. If it does then it could mean that there's a problem in your client. That would be the first thing to check. Going from there you can narrow the problem and hopefully fix it.
If you want to have a starting point with some working code using Socket.io, both server-site (Node.js) and client-side (browser vanilla JavaScript), then you can see the examples that I wrote originally for this answer, that are available on GitHub and on npm:
Socket.IO Server
Socket.IO server example using Express.js:
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
console.error('socket.io connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js
Socket.IO Client
Socket.IO client example using vanilla JavaScript:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html
You can compare the same code with WebSocket versions:
WebSocket Server
WebSocket server example using Express.js:
var path = require('path');
var app = require('express')();
var ws = require('express-ws')(app);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'ws.html'));
});
app.ws('/', (s, req) => {
console.error('websocket connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.send('message from server', ()=>{}), 1000*t);
});
app.listen(3001, () => console.error('listening on http://localhost:3001/'));
console.error('websocket example');
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.js
WebSocket Client
WebSocket client example using vanilla JavaScript:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening websocket connection');
var s = new WebSocket('ws://'+window.location.host+'/');
s.addEventListener('error', function (m) { log("error"); });
s.addEventListener('open', function (m) { log("websocket connection open"); });
s.addEventListener('message', function (m) { log(m.data); });
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/ws.html
I hope this can help you evaluate whether staying with Socket.io or going with WebSocket is the right decision for you, and will give you some working client-side code to test your backend. The code is released under the MIT license (open source, free software) so feel free to use it in your project.

Send messages from server to client socket.io

I am trying to send a message from NodeJS server to client using socket.io
However, I found the same practice all over the internet, which is wrapping the emit with io.on('connection', handler) and then making the server listen on a special "channel" event like so:
var io = require('socket.io')();
var socketioJwt = require('socketio-jwt');
var jwtSecret = require('./settings').jwtSecret;
var User = require('./models/users').User;
io.set('authorization', socketioJwt.authorize({
secret: jwtSecret,
handshake: true
}));
var sockets = [];
io.on('connection', function(socket) {
sockets.push(socket);
});
sendLiveUpdates = function(gameSession) {
console.log(sockets);
}
exports.sendLiveUpdates = sendLiveUpdates;
exports.io = io;
My problem is: I want to emit messages outside this on connection wrapper, example from my routes or other scripts. Is it possible?
Thanks.
Yes. You just need to keep a reference to the socket.
// Just an array for sockets... use whatever method you want to reference them
var sockets = [];
io.on('connection', function(socket) {
socket.on('event', function() {
io.emit('another_event', message);
});
// Add the new socket to the array, for messing with later
sockets.push(socket);
});
Then somewhere else in your code...
sockets[0].emit('someEvent');
What I usually do is assign new clients a UUID and add them to an object keyed by this UUID. This comes in handy for logging and what not as well, so I keep a consistent ID everywhere.

socket.io-client connecting, but not emitting

I am making a little encrypted chat app, in the terminal, using socket.io-client and socket.io. The client is able to connect to the server, but is not emitting the username, when its entered.
Client:
var socket = require('socket.io-client')('http://127.0.0.1:3000');
socket.on('connect_error', function(){
console.log('Failed to establish a connection to the servers, or lost connection');
return process.exit();
});
var prompt = require("prompt-sync")()
var news = "Add news: Will be from database. "
var username = prompt("Username>: ")
console.log("Hold on a sec, just checking that!")
console.log("")
if (typeof username === "defined"){
socket.emit('user-name', {usr: 'username'})
}
socket.on('user-name-good',function(socket){
console.log("Okay! Your username looks good, we just require your password")
console.log("If you chose to have no password, please press enter with out pressing space!")
var password = prompt("Password>: ")
if (typeof password !== "defined"){
console.log("Please provide a password!")
return password = prompt("Username>: ")
}
socket.on('user-name-fail',function(socket){
console.log("Sorry, we could not find, "+username+""+"Please register on the website, or, if you have registered ")
return process.exit()
})
}
)
Server code, is based on code from socket.io chat example:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
I have added a error event, this closes the client if a connection to the server fails, so I know its connecting, any help appreciated, I have done research on this topic, and tried a lot of other methods, but to no avail.
Also the connection is made after you submit data, not when the client code is started, what could be causing this?
If you want to send events between client and server you have to:
Send event A from client to the server and server has to be listening for the A event.
If you want to send event B from server to client then client has to be listening for the event B.
Apart from everything else in your code I don't see where you are listening for the 'chat message' event on the client side.
Socket.io is based on these so called 'events'. The code below is going to send 'my_event' event to the server and the trasmitted data is going to be the object { a: 1 }.
socket.emit('my_event', { a: 1 });
If I want to handle this event on the server I have to listen for it:
socket.on('my_event', function(data) {
// data is the object { a: 1 }
// do stuff..
});

client code in node js

I am new to Nodejs and am trying to set up a server client connection using sockets. Below is my code. Server is working OK but client is not connecting.
Please can anyone help me figure out the mistake.
Much Thanks
jessi
Server.js
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
io.on('data', function(data) {
console.log('DATA from client is: ' + data);
// Close the client socket completely
});
server.listen(4200);
console.log('Monitoring server listening on port 4200');
Client.js
var HOST = '127.0.0.1';
var PORT = 4200;
var express = require('express');
var app = express();
var client = require('http').createServer(app);
var io = require('socket.io')(client);
client.connect(PORT, HOST, function()
{
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected,
// the server will receive it as message from the client
io.write('I am Chuck Norris!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
console.log('DATA: ' + data);
// Close the client socket completely
client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
For the client you use the socket.io-client package instead. The client side doesn't require the use of the Express portion since you're not recreating a web server on the client. If you look at your current code you're essentially recreating the Socket server which isn't what you want to do.
All that is necessary is to create a new Socket.io client and register your various event handlers.
var socket = require('socket.io-client')('localhost:4200');
socket.on('data', function(data) {
// handle incoming data
console.log(data);
});

Node.js websocket-server and tcp-server connection

Related to this question Browser with JavaScript TCP Client I asked whether I can connect from a browser to a tcp server. I found out that it won't work so I asked for another solution. '0101' provided me to built up two servers. One tcp server for a c++ application that connects to and one websockets server that receives data from the browser. I have originally built up each one of them, but I don't know how to connect them so I can receive data from the browser in the c++ application.
Here is the websockets-server:
var ClientListe = {};
// Anzahl der Verbundenen Clients
var ClientAnzahl=0;
// Websocket-Server
var WebSocketServer = require('ws').Server
var wss = new WebSocketServer({host: '127.0.0.1',port: 80});
wss.on('connection', function(ws)
{
// Client-Anzahl hochzählen
ClientAnzahl++;
// Client-Verbindung mit in die Client-Liste Aufnehmen
ws['AUTH'] = ClientAnzahl;
ClientListe[ws['AUTH']] = ws;
// Ausgabe
console.log('client '+ClientAnzahl+' verbunden...');
ws.on('message', function(message)
{
console.log('von Client empfangen: ' + message);
for(client in ClientListe)
{
ClientListe[client].send('von Server empfangen: ' + message);
}
});
ws.on('close', function()
{
// Client aus der ClientListe Löschen
delete ClientListe[ws['AUTH']];
// Nachricht der Trennung an die Console ausgeben
console.log('Client '+ ws['AUTH'] +' getrennt.');
});
});
and here is the tcp server:
// Load the TCP Library
net = require('net');
// Keep track of the chat clients
var clients = [];
// Start a TCP Server
net.createServer(function (socket) {
// Identify this client
socket.name = socket.remoteAddress + ":" + socket.remotePort;
// Put this new client in the list
clients.push(socket);
// Send a nice welcome message and announce
socket.write("Welcome " + socket.name + "\n");
broadcast(socket.name + " joined the server\n", socket);
// Handle incoming messages from clients.
socket.on('data', function (data) {
broadcast(socket.name + " message: " + data, socket);
});
// Remove the client from the list when it leaves
socket.on('end', function () {
clients.splice(clients.indexOf(socket), 1);
broadcast(socket.name + " left the server.\n");
});
// Send a message to all clients
function broadcast(message, sender) {
clients.forEach(function (client) {
// Don't want to send it to sender
if (client === sender) return;
client.write(message);
});
// Log it to the server output too
process.stdout.write(message)
}
}).listen(80);
// Put a friendly message on the terminal of the server.
console.log("TCP Server running at localhost port 80\n");
Both are copied out of the internet for testing some cases
Create a TCP server (NodeJS example)
var net = require("net");
var server = net.createServer(function(c) { //'connection' listener
console.log('server connected');
c.on('end', function() {
console.log('server disconnected');
});
c.write('hello\r\n');
c.pipe(c);
});
server.listen(8124, function() { //'listening' listener
console.log('server bound');
});
Then in the same file (optionally of course) create a WS server with different port number
var WebSocketServer = require("ws").Server;
var wss = new WebSocketServer({
port: 8080
});
wss.on("connection", function(ws) {
console.log("CONNECTED");
// ws.on("message"), ws.on("close"), ws.on("error")
});
Now you should have two servers, one for regular sockets and another one for WebSockets.
// As I mentioned in the previous question and Pete as well, it is a lot better to use WebSockets in C++ as well instead of creating two servers...
Drop the TCP server and make the C++ client connect to the websockets server instead. You'll need to implement the websockets protocol on top of your TCP connection at the C++ end (all you really need is a bit of pre-amble to negotiate the websocket). You have problems here with both servers trying to use port 80.
By the way, you should also consider using HTTPS for the websocket instead of HTTP since it avoids problems with proxy traversal. But get the HTTP case working first as this will be more complicated to implement on the C++ end.

Categories

Resources