How to create custom client events in node.js + socket.io - javascript

I'm just starting out with node.js, and from what I can tell so far, the way clients communicate with the server is through:
//Client Code 1
var iosocket = io.connect();
iosocket.on('connect', function () {
iosocket.send("Here's some info");
});
The server becomes aware of this when the 'message' event is recieved:
//Server Code 1
var socketio = require('socket.io');
var io = socketio.listen(server);
io.sockets.on('connection', function (client) {
client.on('message', function(msg) {
//msg== "Here's some info"
}
});
Now I want the client to be able to provide several distinct events such as:
//Server Code 2
client.on('buttonClicked', function() { ...
client.on('nameChanged', function(newName) { ...
But I'm having trouble figuring out how. The only solution I can come up with using the pieces I have is to send back messages, but have them contain key-value pairs of information:
//Server Code 3
client.on('message', function(msg) {
kvp = message.split(',');
if( kvp[0] == 'buttonClicked' )
...
else if( kvp[0] == 'nameChanged' )
...
}
But I'm certain there's a proper way of doing this that I just haven't seen in any examples yet. I expect that there's something similar to how the server can generate any event it wants using:
//Server Code 4
io.sockets.emit('serverCustomEvent', eventData);
Which are in turn monitored by the client using:
//Client Code 4
iosocket.on('serverCustomEvent', function(data) {
//process data
});
Can someone point me in the right direction?

You can use emit on the client to send custom messages to the server.
iosocket.emit('serverCustomEvent', data);
and on the server
io.sockets.on('connection', function(socket) {
socket.on('serverCustomEvent', login);
});

Related

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..
});

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

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

SocketIO, can't send emit data from client

I'm having the most odd problem trying to send data from a client browser to my node server using SocketIO. Sending from server to client works just fine, but the other way around I get an undefined error. Here's a quick bit of what it looks like, super simple.
Node Server (app.js)
io.on("connection", function(socket) {
socket.on("pageReady", function(data) {
console.log('pageReady called');
console.log(data);
return socket.emit('newline', '###SOCKET STARTED###');
});
socket.on("disconnect", function() {
return console.log('disconnected');
});
});
Browser (client.js)
var socket;
socket = io.connect("http://localhost:5678");
socket.on("newline", function(data) {
return $('#socketData').append('<li>' + data + '</li>');
});
socket.emit("pageReady", "test");
Super simple, right? Nothing special. When I emit from server, works fine, however when the client calls "pageReady". node responds with this.
/Volumes/HOME/Users/user/git/sockettest/app.js:89
console.log(data);
^
ReferenceError: data is not defined
Data should be returning "test", but isn't. What am I doing wrong?
Your client should listen for the socket connection before attempting to emit to it:
var socket = io.connect("http://localhost:5678");
socket.on("newline", function(data) {
return $('#socketData').append('<li>' + data + '</li>');
});
socket.on("connect", function() {
socket.emit("pageReady", "test");
});

Node.js calling a function from script to update UI

Here is my webserver:
var net = require('net');
var server = net.createServer(function(socket) {
socket.write('hello\n');
socket.write('world\n');
//RECEIVE PACKET ON SOCKET
socket.on('data', function(data) {
//socket.write(data);
//console.log(data);
testSocketData(data)
});
});
server.listen(8000);
And the method testSocketData(data) is located in file update_ui.js and does the following:
function testSocketData(test) {
$('#p1').text(test)
}
Where #p1 refers to the id of a paragraph element in my main.html. I know that my socket is working, however I get:
ReferenceError: testSocketData is not defined.
How can I simply pass off the data received from my node.js server to the rest of my web application?
You must move that method(with socket.on('data') as well) from the server to the client side. When you receive a message via socket, the p1 element will update its text too.
On the server you will still need to have a socket.on('data') to receive the messages from the client.
Edit:
Here is some code, a little bit changed from my comment below.
On server:
function computeSomeResults(data) {
// your logic here
}
socket.on('servermsg', function(data) {
var result = computeSomeResults(data);
socket.emit('clientmsg', result);
});
On client:
function testSocketData(test) {
$('#p1').text(test);
}
socket.on('clientmsg', function(data) {
testSocketData(data);
// emit something maybe?
}
Eventually, you may want to send something to the server:
$('#p1').on('click', function(){
socket.emit('servermsg', $(this).text());
});

socket.io: client-side emit callback never fires

Messing around with socket.io just for proof of concept, everthing is working great so far except I can't get my emit callback to work on the client side. I've got to be missing something stupid here, but documentation is not killer at the moment. The server picks up the "getSomeData" event just fine, no errors anywhere.
From what I could tell in the client socket.io source, it checks if the last argument to emit is a function and always uses it as a callback, but debugging any deeper than that was problematic for me.
I feel like I have to be missing some core concept here..Is this not what this.send(..) is supposed to do? I could find only 1 useage in the example apps, and none where the client side code for that event emission was available.
Update: just to be clear, I am in fact intentionally emitting the event client side. The purpose of this was to see if socket.io could be used to allow clients to pull data on request in addition to receiving pushes.
server:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.on("getSomeData", function() {
this.send({data: "some random data"});
});
});
client: (console.log never happens)
<script type="text/javascript" src="http://localhost/socket.io/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect('http://localhost');
socket.emit("getSomeData", function(data) {
console.log(data);
});
</script>
It looks like you have some logic switched around, try...
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.emit("getSomeData",{data: "some random data"});
});
and client...
<script src="http://localhost/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on("getSomeData", function(data) {
console.log(data);
});
</script>
EDIT:
var io = require('socket.io').listen(80);
io.sockets.on('connection', function (socket) {
socket.on("getSomeData", function(name,fn) {
fn({data: "some random data"});
});
});
Client
<script src="http://localhost/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.emit("getSomeData", function(data) {
console.log(data);
});
</script>
In Liam William's answer, I found it was necessary to send the callback (or acknowledgement function) as the third argument on the client emit:
Client:
<script src="http://localhost/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.emit("getSomeData", null, function(data) {
console.log(data);
});
You can have the callback, but you have to do it a bit differently:
Server: (app.js)
var io = require('socket.io')(80);
io.on('connection', function (socket) {
// please note that server will take 2 data entries as function parameter below
socket.on('ferret', function (name, fn) {
fn('woot');
});
});
Client (index.html)
var socket = io(); // TIP: io() with no args does auto-discovery
socket.on('connect', function () {
socket.emit('ferret', 'tobi', function (data) {
console.log(data); // data will be 'woot'
});
});
Actaully, socket io also mentions this one; sending-and-getting-data-(acknowledgements)

Categories

Resources