socket.io implementing a simple chat - node.js

I tried to ask this on the socket.io google group but no one could (or didn't wanted to) help me.
I have this piece of code on the server side:
var chat = io
.of('/chat')
.on('connection', function (socket) {
socket.emit('message', {
that: 'only'
, '/chat': 'will get'
});
});
chat.on("message", function(data){
console.log(data);
});
While on the client side I have this code:
var chat = io.connect('http://localhost/chat');
chat.on('message', function (data) {
chat.emit('hi!');
});
chat.emit("message", {"this": "is a message"});
On the console I can see that the first message from the server is sent but it seems like the client, once connected and received the message, doesn't emit the 'hi!' message. Moreover I want the client to emit also another message, namely the last line I pasted. Also this message is not received by the server (which in theory should log it).
I'm surely doing something wrong, can anyone point out where exactly this is happening?
What I want to achieve in the end is just setting up a simple chat-like system, but I want this stuff (the channels) working before actually writing the chat itself. Thanks

The reason why that it doesn't the "hi" is not sent is because the first argument in .emit is the event name, in which in here, it is "hi". Technically if you do the following on the server side, I think you should get an undefined data(since you didn't put anything as the second argument which is the object to be sent):
.on('hi',function(data){
console.log(data) // should log "undefined"
});
You can also use .send which is like the web-sockets semantics, and sends to the the message event. If you change the .emit to .send in the client side, it should work.
In summary:
.emit('eventName', 'data') // sends to the eventName name
.send('data') // sends to message event
Working client side code:
var chat = io.connect('http://localhost/chat');
chat.on('message', function (data) {
chat.send('hi!');
});
chat.emit("message", {"this": "is a message"});

I dumbed it down a little bit, but:
Server:
var io = require('socket.io').listen(8080);
var chat = io
.of('/chat')
.on('connection', function (socket) {
socket.send('welcome to the interwebs');
socket.on('message', function(data) {
console.log(data);
});
});
Client:
<html>
<body>
<script src="http://10.120.28.201:8080/socket.io/socket.io.js"></script>
<script type="text/javascript">
var chat = io.connect('http://10.120.28.201:8080/chat');
chat.on('connect', function () {
console.log("connected");
chat.send('hi!');
chat.on('message', function (data) {
console.log(data);
});
});
</script>
</body>
</html>

Related

Socket.io, Node, Corodva, I don't recive message in client receptor

I have a problem when I try send message from a client emisor with "emit" and I try catch the message with "on" in a client receptor.
I don't know what is the problem, my code is this:
Emisor Client:
socket.emit("callDriver", data);
Receptor Client:
socket.on("sendToDriver", function(data){
console.log(data);
})
Server:
var io = require('socket.io')(server);
io.on('connection', function(socket){
socket.on('callDriver', function(data){
console.log(data);
socket.emit('sendToDriver', data);
})
})
Thanks community
Guys I resolved the problem, it's strange in the official documentation of Socket.io they say that when you send data in a .emit you should send this with "socket.emit()" (server side) but I try change socket for io and with this mode work it.
In conclusion:
// I changed this:
io.on('connection', function(socket){
socket.on('callDriver', function(data){
console.log(data);
socket.emit('sendToDriver', data);
})
})
// for this:
io.on('connection', function(socket){
socket.on('callDriver', function(data){
console.log(data);
io.emit('sendToDriver', data);
})
})
Thanks guys!
Here is a simple rooms solution for you. The init() part is very low-tech/simple but you did not say how you intend to populate the socket server with the client userId/session-data when you connect to the server for the first time.
//Client
socket.on('connect',()=>{
socket.on('init',()=>{
socket.emit('init', 'userid')
})
})
socket.on("sendToDriver", function(message){
console.log(message);
})
sendMessage(message){
let data = {userId: "userId", message: message}
socket.emit("callDriver", data);
}
//Server
var io = require('socket.io')(server);
//Triggered by each client separately.
io.on('connection', function(socket){
socket.on('init', (driverId)=>{
//When your web socket starts for the first time, each user creates their own room with their main userId that is used in your mobile app.
//Your setup is so basic, that the server('connection') -> server.emit('init') -> client.on('init') -> client.emit('init') flow is the most sane example for now.
//However this init() setup is primitive -- you need an authentication flow and to pass up the userId/session data with a socket.io 'middleware' function or the 'socket.io-auth' library (recommended)
socket.join(driverId)
})
socket.emit('init')
//Data sent to callDriver will contain the userId of the desired receipient. Since this user is already waiting in that room for us, we join it,
//send the message, and then leave immediately.
socket.on('callDriver', function(data){
socket.join(data.driverIdToCall)
socket.to(data.driverIdToCall).emit('sendToDriver', data.message);
socket.leave(data.driverIdToCall)
})
})

Node.js emit not working on specific socket.on

I'm trying to send news to my client. On connect, it works great, but for some reason on broadcast2 it wont get any response client sided, even know its the same piece of code, and even that broadcast2's console.log is working.
Q: How can i make sure broadcast2 emit will work?
This works:
socket.on('message', function (data) {
console.log('message gotten');
socket.emit('news', { message: 'xxxx' });
});
this wont work:
socket.on('broadcast2', function (data) {
console.log("broadcast revieced");
socket.emit('news', { message: 'xxxx' });
});
this is node.js response:
total code in node.js
socket.on('message', function (data) {
console.log('message gotten');
});
socket.on('another-message', function (data) {
socket.emit('not-news', { hello: 'world' });
});
socket.on('broadcast2', function (data) {
console.log("broadcast revieced");
socket.emit('news', { message: 'xxxx' });
});
and this on the client side:
var socket = io.connect('mysite:8080');
function sender() {
console.log('sending tester');
socket.emit('sendertester', 2);
}
socket.on('connect',function(){
});
socket.on('tester', function(msg){
console.log("callback");
});
socket.on('news', function(message) {
console.log("INCOMMING NEWS");
console.log(message);
});
UPDATE 1:
The broadcast2 socket, sent by PHP:
function broadcast($message,$broadcast = 'broadcast2') {
$client = new Client(new Version1X('myurlhidden:8080'));
$client->initialize();
$client->emit($broadcast, ['message' => $message]);
$client->close();
}
UPDATE 2:
**Question two: Cause my broadcast2 is sent before the client sided is loaded, and then the client connects to the node, could that be the cause?
But in the same time, im already preloading the class that holds the broadcast2 emitter.
Using codeigniter framework.**
UPDATE 3
I was trying to check my theory on update 2, by having two users logged in, while user one trying to perform the trigger. user two gets no output, so i suppose that theory is busted.
The server cannot send a message to any socket before it is connected. You have to wait until you have something listening to receive what you are sending.
I wouldn't call close after the emit either, as you may close the connection before the client has received the message, emit doesn't wait for the client to receive the data before returning its asynchronous.
Instead let the clients close the connections when they terminate.

Using Socket.io, how do I detect when a new channel/room has been created?

From the server, I want to be able to detect when a client creates new a room or channel. The catch is that the rooms and channels are arbitrary so i don't know what they will be until the user joins/subscribes. Something like this:
Server:
io.on('created', function (room) {
console.log(room); //prints "party-channel-123"
});
Client:
socket.on('party-channel-123', function (data) {
console.log(data)
})
I also can't have any special client requirements such as sending a message when the channel is subscribed as such:
socket.on('party-channel-123', function (data) {
socket.emit('subscribed', 'party-channel-123');
})
Server:
io.sockets.on('connection', function(socket) {
socket.on('createRoom', function(roomName) {
socket.join(roomName);
});
});
Client
var socket = io.connect();
socket.emit('createRoom', 'roomName');
the io object has references to all currently created rooms and can be used as such:
io.sockets.in(room).emit('event', data);
Hope this helps.
PS. I know its emitting the 'createRoom' that you probably don't want but this is how socket.io is used, this is pretty much copy/paste out of the docs. There are tons of examples on the socket.io website and others.

Socket.io 1.0 Middleware join room not working properly

I tried to add new socket to some rooms in a middleware, but it seems not working while a first emit haven't be done for a socket(client side). When a socket (client side) send a 'message' event it will then work and be part of the room.
Is it a normal behavior?
Am I mandatory to join room in 'connection' event?
app.js (server side)
var app = require('http').createServer(function (req, res){
res.end('no rest');
});
var io = require('socket.io')(app);
app.listen(7076);
io.use(function(socket, next){
socket.join('toto');
next();
});
io.on('connection', function (socket) {
socket.on('message', function (data) {
socket.to('toto').emit('message', data);
});
});
According to the documentation, socket.to('toto').emit... syntax is not correct. You should use one of the following forms:
send everyone in "toto" room:
io.to('toto').emit('message', data);
send everyone in "toto" room except the sender:
socket.broadcast.to('toto').emit('message', data);
In fact the problem wasn't on the server side at all... It was my client that i didn't describe.
When clicked on a button to send a message here is the function called
function messageManagement(cb)
{
var message = $('#message_text').val();
if (!message || message.length == 0)
message = 'I am watching you';
socketClient.emit('message', {message:message});
socketClient.on('message', function (data){
console.log(data.messsage);
drawMessage(data);
});
}
As you can see each time the client emit a message it also register to the response event. So each time I emit a message a registered one more time to same event... It was messy so i changed this and it worked..

Socket.io : How do I handle all incoming messages on the server?

I want to be able to handle all messages that are coming in from clients in a single handler.
Example client code:
var socket = io.connect('http://localhost');
socket.emit('news', { hello: 'test' });
socket.emit('chat', { hello: 'test' });
Example server code:
io.sockets.on('connection', function (socket) {
socket.on('message', function (data) {
console.log(data);
}); });
I'd like to be able to log every message even if its sent on news, chat or whatever other name using emit. Is this possible?
Note: The above server code does not work. There is nothing currently logged. I am just wondering if there is a single event which could be handled for all messages for every emit name.
That is possible by overriding socket.$emit function
//Original func
var x = socket.$emit;
socket.$emit = function(){
var event = arguments[0];
var feed = arguments[1];
//Log
console.log(event + ":" + feed);
//To pass listener
x.apply(this, Array.prototype.slice.call(arguments));
};
It's even easier on Socket.Io >3 using the socket.onAny(listener):
this.socket.onAny(m => {
..
});
This is supported out of the box now as of Socket-io 2.0.4, you simply need to register a middle ware (source from socketio-wildcard):
As of Socket.io v2.0.4 (commit), you can use a socket middleware to
catch every incoming Packet, which satisfies most of
socketio-wildcard's use cases.
io.on('connection', (socket) => {
socket.use((packet, next) => {
// Handler
next();
});
});
This is an open issue with Socket.IO.
At this time, if you really need it, you will probably have to fork Socket.IO. See 3rd-Edens comment for how to do it.

Resources