socket.to(socket.id).emit() does not work - node.js

Trying to execute the simplest of targeted messaging in socket.io with no success. According to the documentation for socket.io with express.js you can target a message to a single user socket with socket.to(socket.id).emit('event name', 'message')
I have already read the socket.io docs from start to finish and other stack overflow Q/A here and here and here. Some of the solutions I find involve creating rooms and messaging those rooms, but the objective of this question is to send a message to the socket id using socket.to(socket.id).emit('event name', 'message') as given in the socket.io documention.
I'm using node v6.11.2, express 4.15.2 and socket.io 2.0.3.
The client and server code are taken almost verbatim from https://socket.io/get-started/chat/ with minor changes while I experiment.
index.js
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){
console.log(req.ip+' connected');
socket.on('chat message', function(msg){
console.log(socket.id);//logs the socket id. Something like 'AUCyM1tnpinCfvfeAAAB'
console.log(msg);//logs whatever the message was, so I know the server is receiving the message
socket.to(socket.id).emit('chat message', 'Nothing is happening here.');
});
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
index.html
<!doctype html>
<html>
<head>
<title>Socket.IO chat</title>
<style>
...
</style>
</head>
<body>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
</body>
</html>

Change this:
socket.to(socket.id).emit(...)
to this:
socket.emit(...)
Here's an explanation. socket.to(socket.id).emit(...) will broadcast to the room named socket.id. That's OK, there is a room with that name and socket is the only member. But, socket.to() sends to all members of that room EXCEPT socket so there's nobody to send it to.
So, if you want to send just to socket, then just use socket.emit().
Here's a quote from the socket.io doc for socket.to():
Sets a modifier for a subsequent event emission that the event will
only be broadcasted to clients that have joined the given room (the
socket itself being excluded).

Change this :
socket.to(socket.id).emit('chat message', 'Your message');
To this :
io.to(socket.id).emit('chat message', 'Your message');
if you want you can check this link : https://socket.io/docs/emit-cheatsheet/

Related

How to best use socket.io and pub/sub to create connection to API call - Nodejs

I have created my first application of Nodejs. I am using socket.io and express. I tried this tutorial: https://socket.io/get-started/chat/ and I find emit is what I might need not sure.
My application shows stock tickers, I am using API's, I have url like: https://quotes.example.com/v1/file.json/johndoe?&_token=tokenumber
All the users who open http://example.com/live page, I would like to push or emit stock tickers to this page. How do I best achieve this? I get the idea of live page needs to be a channel to which all user would subscribe and I am pushing data to it.
I have never worked on real-time apps before, all suggestions are welcomed.
Edited
Front-end code
<!doctype html>
<html>
<head>
<title>Live Stock Quotes App</title>
<style>
body { font: 26px Helvetica, Arial; font-weight:bold;}
#livequotes { text-align: center;}
</style>
</head>
<body>
<p id="livequotes"></p>
<script src="/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io('/channel1');
socket.on('live-quote', function(msg){
$('#livequotes').text(msg);
});
});
</script>
</body>
</html>
server-side code
var app = require('express')();
var http = require('http').Server(app);
var httpk = require('http');
var io = require('socket.io')(http);
var nsp = io.of('/channel1');
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
nsp.on('connection', function(socket){
nsp.emit('live-quote', 'Welcome User!');
//Make a http call
function test()
{
httpk.get("url-to-api", function(res) {
var body = ''; // Will contain the final response
res.on('data', function(data){
body += data;
});
res.on('end', function() {
var parsed = JSON.parse(body);
console.log(parsed.johndoe.bid_price);
return parsed.johndoe.bid_price;
});
});
}
setInterval(test,500);
socket.on('disconnect', function(){
console.log('1 user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
Above code I have put as you suggested. Now, I wanted to do add something like:
setInterval(test,500);
function test (){
http.get("url-for-api", function(res) {
var body = ''; // Will contain the final response
res.on('data', function(data){
body += data;
});
// After the response is completed, parse it and log it to the console
res.on('end', function() {
var parsed = JSON.parse(body);
console.log(parsed.johndoe.bid_price);
data = parsed.johndoe.ask_price;
});
})
// If any error has occured, log error to console
.on('error', function(e) {
console.log("Got error: " + e.message);
});
}
It's not entirely clear exactly what you're asking, but I'll take a stab at it.
If you want to be able to "push" new stock updates to a client using socket.io, then the usual way you would do that is a client would make a socket.io connection to your server and then your server can issue updates to all connected clients by doing an io.emit(msg, data) on the server. That will send that message and data to all connected clients.
If you want these updates to be sent to a web page, then you put Javascript in that web page that makes the socket.io connect to your server and then listens on that socket for the appropriate messages from the server. When it receives the messages from the server, it can then insert them into the page in whatever fashion you find appropriate.
This client code from the socket.io doc pages would be typical of the client-side:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
socket.on('udpate', function (data) {
console.log(data);
// do something with the data here (like insert it into the web page)
});
</script>
If you have to tell the server which stock updates you're interested in so only those updates are sent to the client page, then you will need to do more work on both client and server to allow the server to keep track of which connection is interested in which updates and only send to the right connections. You could use socket.io rooms to help manage that. A client connection requests to join a room for a given stock and then stock updates for a particular stock are sent only to the clients in that corresponding room.

Socket.io failing to log chat message in console

I'm walking through the Socket.io tutorial on creating a chat room, and I'm having trouble getting my app to log the chat message to the console.
The app is logging when a user connects & disconnects, but it is not logging when a message is passed through.
Any thoughts?
The relevant parts of my index.html page:
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script>
var socket = io();
$('form').submit(function() {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
</script>
<body>
<ul id="messages"><ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
My index.js file:
var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.use(express.static('public'));
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('chat message', function(msg) {
console.log("message: " + msg);
});
});
I've gotten it to work!
Steps to solution:
- separate the script tag with the event listener into a separate JS file
- include that JS file in the same place the script tag was originally
- load the chatListener when the document is ready
My files now look like this and everything works beautifully:
index.html:
<script src="/socket.io/socket.io.js"></script>
<script src="http://code.jquery.com/jquery-1.11.1.js"></script>
<script src="main.js"></script>
<body>
<ul id="messages"><ul>
<form action="">
<input class="chat" id="m" autocomplete="off" />
<input class="btn" type="submit" value="Send" />
</form>
</body>
index.js: nothing changed
main.js:
var socket = io();
var chatListener = function() {
$('form').submit(function() {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
}
$(document).ready(function() {
chatListener();
})
In the end, I think it was a beginner's JS mistake; I was loading the script at the top of the page (as the tutorial suggested), and the event listener on the form was never registering.

Issue in connecting Rails client to Node server

I have a chat application on Nodejs+Socket.io which is running on http://localhost:5001 and the other hand there is a rails application which is running on http://localhost:3000
What i want to achieve ?
Connect rails client to node server to talk to each other.
What i did ?
Node server working properly
Added in rails chat page.
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off"/>
<button>Send</button>
</form>
<script src="http://localhost:5001/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost:5001');
socket.on('connect', function (data) {
console.log('connected!');
});
</script>
<script>
var socket = io();
$('form').submit(function () {
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function (msg) {
$('#messages').append($('<li>').text(msg));
});
</script>
What is the issue ?
The moment i am loading the page it is showing connected (connected to Node server side also) but just after the first page load port becomes 5001 to 3000 and obviously 404 for socket.io.

NodeJS and socket.io can't send message

today I follow an tutorial by Gonzalo Ayuso at http://gonzalo123.com/2011/05/23/real-time-notifications-part-ii-now-with-node-js-and-socket-io/ but it can't send the message
Here is my server.js
var http = require('http');
var io = require('socket.io');
server = http.createServer(function(req, res){
});
server.listen(8000);
//socket.io
var socket = io.listen(server);
socket.set('transports', ['websocket']);
console.log("Start");
socket.on('connection', function(client){
client.on('message', function(msg){
console.log(msg);
socket.broadcast(msg);
})
});
and the client.html
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Comet Test</title>
</head>
<body>
<p><a id='customAlert' href="#" onclick='socket.send("customAlert")'>publish customAlert</a></p>
<p><a id='customAlert2' href="#" onclick='socket.send("customAlert2")'>publish customAlert2</a></p>
<script src="http://localhost:8000/socket.io/socket.io.js" type="text/javascript"></script>
<script type="text/javascript">
// Start the socket
var socket = io.connect('http://localhost:8000');
socket.on('message', function(msg){
console.log(msg);
});
</script>
</body>
</html>
I have edited it just a little bit to run on my server. But the client doesn't send message to server. Can anybody help me? Sorry for my bad English.
I have found out that the client can't connect to server but I don't know why?
My computer is running xampp with apache server. Maybe it's problem?
Updated:
I have just set transports to xhr-polling and it connect success. Why doesn't it accept websocket?
you need to read more carefully the tutorials about socket.io
first of all to call some event, you need to emit the event name:
socket.emit('my other event', { my: 'data' });
thats mean, on your onclick in anchor need to call socket.emit ..., or to call some function like:
function call_my_event(name){
socket.emit(name,{my : 'data'});
}
I have found out my problem. It's about firewall or proxy or something else in my computer block websocket protocol. I tested that code on another computer and it works fine. So I have to re-install my system and websocket is available for me :D

Redis Cookbook Chat Recipe

I am a new starter to Node.Js and Redis. I got the Redis cookbook and was trying out the Chat client & Server recipe.
I was wondering if anybody got the code to work or if there is some bug in the code.
I dont see where the sent messages from the client get invoked on the server.
Any help would be great.
Regards,
Tom
Client Code:
<?php
?>
<html>
<head>
<title></title>
<script src="http://192.168.0.118:8000/socket.io/socket.io.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script>
var socket = io.connect('192.168.0.118',{port:8000});
socket.on('message', function(data){
alert(data);
//var li = new Element('li').insert(data);
//$('messages').insert({top: li});
});
</script>
</head>
<body>
<ul id="messages">
<!-- chat messages go here -->
</ul>
<form id="chatform" action="">
<input id="chattext" type="text" value="" />
<input type="submit" value="Send" />
</form>
<script>
$('#chatform').submit(function() {
socket.emit('message', 'test'); //$('chattext').val());
$('chattext').val(""); // cleanup the field
return false;
});
</script>
</body>
</html>
Server Code:
var http = require('http');
io = require('socket.io');
redis = require('redis');
rc = redis.createClient();
//rc1 = redis.createClient();
rc.on("connect",function(){
rc.subscribe("chat");
console.log("In Chat Stream");
});
rc.on("message",function (channel,message){
console.log("Sending hope: " + message);
//rc1.publish("chat","hope");
socketio.sockets.emit('message',message);
});
server = http.createServer(function(req,res){
res.writeHead(200,{'content-type':'text/html'});
res.end('<h1>hello world</h1>');
});
server.listen(8000);
var socketio = io.listen(server);
It looks like you're not listening for any connect / message events from socket.io.. try something like
socketio.sockets.on('connection', function(socket) {
console.log("Got connection");
socket.on('message', function(msg) {
rc1.publish("chat", msg);
});
});
You'll need to uncomment your rc1 up there, you will need that second redis connection

Resources