Socket.io-1.0 get clients from namespace - socket.io-1.0

I work with socket.io 1.0 and maybe I'm wrong with my conception.
Actually, I open a namespace server side with
var nsp = io.of('/myNamespace');
And clients connect with
var socket = io.connect('http://localhost/myNamespace');
I can start communication without problems.
Server side I catch signals with
nsp.on('connection', function(socket){
socket.on('disconnect', function(){
//problem here
});
});
In the disconnect I would like to disconnect all sockets connected to my namespace, so i tried to do
for(var myParticipantID in io.sockets.adapter.nsp.connected)
{
io.sockets.adapter.nsp.connected[myParticipantID].disconnect();
}
but it doesn't work ... I don't have error but clients still connecting
I tried with
io.sockets.nsp.clients();
but I have error since socket.io 1.0
I don't want to create room, but maybe it's my mistake?
Thanks for your help,
MagicDenver

If it would help somebody,
I work with node js so I created a value:
app.set(idNameSpace,[]);
and push socket when I have a new connection

You should use the io.of(namespace) function to get connected clients.
for (var id in io.of('/namespace').connected) {
var s = io.of('/namespace').connected[id];
s.disconnect();
}
If you don't know the namespace and you are in a socket.on statement, you can use socket.nsp.connected instead of io.of('/namespace').connected

Related

ApolloServer: "Could not connect to websocket endpoint ws://localhost:4000/subscriptions. Please check if the endpoint url is correct."

I can't implement any subscriptions because it suddenly disconnects from it when I try to listen to some endpoint with GraphQL Playground:
{"error": "Could not connect to websocket endpoint wss://localhost:4000/graphql. Please check if the endpoint url is correct."}
I'm using ApolloServer alone, no express or anything else. It is containerized with Docker using node14 image, the port is properly fowarded, queries and mutations works properly.
This is the configuration snippet:
const server = new ApolloServer({
typeDefs: mergedTypeDefs,
resolvers: mergedResolvers,
playground: {
subscriptionEndpoint: 'ws://localhost:4000/graphql'
},
subscriptions: {
keepAlive: 9000,
onConnect: (connParams, webSocket, context) => {
console.log('CLIENT CONNECTED');
},
onDisconnect: (webSocket, context) => {
console.log('CLIENT DISCONNECTED')
}
},
context: {
models
}
});
I tried everything, from using 'wss' instead of 'ws' to change the path. I checked for typos and didn't find one. What bothers me is that the paths are the same so It should at least try to notify me by the onConnect or onDisconnect but it doesn't.
This is the message through Chrome's dev tools:
WebSocket connection to 'wss://localhost:4000/graphql' failed: WebSocket is closed before the connection is established.
I tested subscriptions with a 'tutorial' project outside the container and it works fine.
Sometimes, the only function of subscriptions that works is onDisconnect but after 2-5 seconds after receiving the error message on PlayGround, and Still it doesn't gives me any insight on the problem.
Any help or suggestion is appreciated.
wss will definitely not work locally without certificate, so use ws as a protocol.
If it works without Docker, then everything should be fine code-wise.
You should also make sure that you've mapped ports correctly, i.e. exposed port 4000 https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose

Can't connect to server with socket.io on both client and server

I just started building me server using socket.io for both my client and Node.js server side.
I'm writing an Objective-c project so i walk through the process of adjusting my project to use Swift alongside with Objective-c which was a pain but it seems to be ok now.
The thing is, when i try to do a simple connect to my server, which prints to log on each connection, nothing happens.
This is the code for the server (Taken from here):
var fs = require('fs')
, http = require('http')
, socketio = require('socket.io');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-type': 'text/html'});
}).listen(8080, function() {
console.log('Listening at: http://localhost:8080');
});
socketio.listen(server).on('connection', function (socket) {
console.log('Connected');
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
Super simple, really nothing to it.
And the Objective-c code for my client which is even more simple:
- (void) connect
{
SocketIOClient* client = [[SocketIOClient alloc]initWithSocketURL:#"http://127.0.0.1:8080/" options:nil];
[client connect];
}
But i can't see nothing on my console except the Listening at: http://localhost:8080 message.
I can't seem to find what i'm doing wrong here, and the fact that the swift debugging is horrible in this combined project, i can't really fully go through the socket.io debugging myself (but i'm pretty sure nothing's wrong with their code)
Any help would be much appreciated.
plz confirm, if you are using the simulator for iOS testing. For device, you need to assign public address to your NodeJS server, and then need to use it's ip in iOS Codebase.
I had used https://github.com/pkyeck/socket.IO-objc during my last project and it worked like a charm.
For simulator, your code should ideally work.

Bridging a simple Node.js & Socket.io chat app with a Rails app (on Heroku)

I have a basic Node.js & Socket.io chat application running on Heroku that I want to integrate into my main rails website. I understand the way to do this is to have two separate Heroku apps - one for rails, one for Node.js.
It doesn't appear to be as simple as moving the client html from the node app to the rails app (giving it the other app's url in 'io.connect();').
The chat app server seems to automatically call the client index.html its own application, and not allow an external source to connect to it. Removing the code that does this (marked below) does not make it work.
I'm painfully new to Node.js & Socket.io and am hoping that this might be a relatively simple fix for a pro.
I believe the functionality I'm after here works in Liam Kaufman's excellent rails/node.js/socket.io example - his node.js server code is here: https://github.com/liamks/Chatty-Node-Server/blob/master/chat-server.js
I've tried mocking my app's code up to be like his, but haven't yet been able to make it work. He e.g. appears to use an 'http' server, whereas mine uses an 'express' server - I wondered if this might be relevant.
Any help would be greatly appreciated.
UPDATE: Ok, so a bizarre turn of events, thanks to redhotvengeance's reply below I've got this working - server is up on heroku and my client html and javascript connects to it. Great - code below. The problem is, however, that the client html file only connects when it's outside of the Rails app!! i.e. on my desktop!! The moment I put it in the rails application's public/ folder or in a view on my localhost, I get nothing! This makes no sense. I checked it wasn't because of any other random erroneous javascript in my asset pipeline conflicting by just creating a new rails app and dropping the html file in the public/ folder - again nothing - just a dead html page that doesn't connect. Does anyone have any idea what might be going on here? Does Rails have some security feature in place that stops connections to external servers or something??
UPDATE 2: I'm told this has something to do with the 'same origin policy', and I'm in trouble. Is there any way around it? Seems Liam didn't have this problem.
Client:
<script src="http://calm-sands-3826.herokuapp.com/socket.io/socket.io.js" type="text/javascript"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script>
var socket = io.connect('http://calm-sands-3826.herokuapp.com');
// on connection to server, ask for user's name with an anonymous callback
socket.on('connect', function(){
// call the server-side function 'adduser' and send one parameter (value of prompt)
socket.emit('adduser', prompt("What's your name?"));
});
// listener, whenever the server emits 'updatechat', this updates the chat body
socket.on('updatelog', function (username, data) {
$('#log').append('<b>'+username + ':</b> ' + data + '<br>');
});
// listener, whenever the server emits 'updateusers', this updates the username list
socket.on('updateusers', function(data) {
$('#users').empty();
$.each(data, function(key, value) {
$('#users').append('<div>' + key + '</div>');
});
});
</script>
<div style="float:left;width:100px;border-right:1px solid black;height:300px;padding:10px;overflow:scroll-y;">
<b>USERS</b>
<div id="users"></div>
</div>
<div style="float:left;width:300px;height:250px;overflow:scroll-y;padding:10px;">
<div id="log"></div>
</div>
Server:
var port = process.env.PORT || 5001;
var io = require('socket.io').listen(parseInt(port));
io.configure(function(){
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
io.set("close timeout", 10);
io.set("log level", 1);
})
// usernames which are currently connected to the chat
var usernames = {};
io.sockets.on('connection', function (socket) {
// when the client emits 'adduser', this listens and executes
socket.on('adduser', function(username){
// we store the username in the socket session for this client
socket.username = username;
// add the client's username to the global list
usernames[username] = username;
// echo to client they've connected
socket.emit('updatelog', 'SERVER', 'you have connected');
// echo globally (all clients) that a person has connected
socket.broadcast.emit('updatelog', 'SERVER', username + ' has connected');
// update the list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
});
// when the user disconnects.. perform this
socket.on('disconnect', function(){
// remove the username from global usernames list
delete usernames[socket.username];
// update list of users in chat, client-side
io.sockets.emit('updateusers', usernames);
// echo globally that this client has left
socket.broadcast.emit('updatelog', 'SERVER', socket.username + ' has disconnected');
});
});
If what you're trying to do is connect pages in your Rails app to your seperate Node.js app running socket.io, then skip setting up Express entirely. You're not looking to actually serve pages from your Node app, just connect users to the socket.io server.
Let's say your Node.js app on Heroku is called: my-awesome-socket-app.
my-awesome-socket-app:
var io = require('socket.io').listen(parseInt(process.env.PORT));
io.configure(function () {
io.set("transports", ["xhr-polling"]);
io.set("polling duration", 10);
});
io.sockets.on('connection', function (socket) {
socket.on('disconnect', function () {
io.sockets.emit('user disconnected');
});
});
Then, in the Rails pages you want to connect to the socket.io server:
<script src="http://my-awesome-socket-app.herokuapp.com/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://my-awesome-socket-app.herokuapp.com');
socket.on('connect', function (data) {
console.log('connected!');
});
</script>

How to connect multiple socket.io clients to different URLs in Node.js?

I am trying to connect many socket.io clients for different URLs in Node.js like so :
app.get('/:id',function(req,res){
io.of('/'+id).on('connection',function(socket){
socket.emit('hello');
})
});
This works however there is a problem :
When a browser refreshs the page http://localhost:3000/xyz for example, the event socket.emit gets fired two times.
If someone accesses the page http://localhost:3000/xyz 10 times, then the event fires 10 times.
This is not good because everytime the user visits that page, the socket events will be fired n+1 times.
What should be done so that I can register sockets to different URLs and at the same time not have this anomaly .
Another thing :
If I do this :
var sock;
io.of('/'+xyz).on('connection',function(socket){
sock=socket;
})
app.get('/:id',function(req,res){
sock.emit('hello');
})
If I use the above code then the socket doesn't get saved succesfully to the sock variable in time. What that means is , I have to do a setInterval of about 1000 .. so that the
sock=socket
line gets fired.
Please help me.
Because with this, in each request to http://localhost:3000/id, you register a new handler, you should be doing that once, not at every request.
app.get('/:id',function(req,res){
io.of('/'+id).on('connection',function(socket){
socket.emit('hello');
})
});
I use below approach to achieve this goal:
client side:
var socket = io.connect('http://localhost:8183/?clientId='+clientId,{"force new connection":true});
server side:
var io = require('socket.io').listen(server);
io.sockets.on('connection', function(socket) {
console.log("url"+socket.handshake.url);
clientId=socket.handshake.query.clientId;
console.log("connected clientId:"+clientId);
});
reference:https://github.com/LearnBoost/socket.io/wiki/Authorizing#global-authorization

Backbone Model from Hub in SignalR

How can i create/convert this script into model in Backbone that can use SignaR Hubs? For example:
<script type="text/javascript">
$(function () {
// Proxy created on the fly
var chat = $.connection.chat;
// Declare a function on the chat hub so the server can invoke it
chat.addMessage = function (message) {
alert("message");
};
// Start the connection
$.connection.hub.start();
});
</script>
EDIT
I did come up with this:
window.Message = Backbone.Model.extend({
hub: undefined,
initialize: function () {
this.hub = $.connection.message;
},
addMessage: function (message) {
alert(message);
},
connect: function () {
$.connection.hub.start();
var messages = this.hub.getAll();//get messages
}
});
but this is not working due to the following error:
this error: :55885 Unexpected response code: 200
If you use default settings SignalR will first try to send a websockets poll to the server. The :55885 is simply the port number of your server. Websockets protocol expects a response status code of 101 (see http://dev.w3.org/html5/websockets/).
If running IIS, unless you run Windows 8 with ASP.NET 4.5 your webserver, it will not recognize a web sockets request and (begin speculation) treat it as a normal get request and return status code 200 (OK) (end speculation) which is an unexpected response in the eyes of the websockets initiator. When this happens SignalR falls back to longpolling instead.
This might not answer your question but it will help you understand the error you get (which is likely not the reason why your code doesn't work)
Also, check out http://srtsolutions.github.com/backbone.signalr/ which is a Backbone.js/SignalR integration Nuget package.

Resources