I'm running two instances of socket.io on my local machine (two namespaces). The present issue is that when trying to connect from the client side (to any namespace), I get the following error:
Uncaught ReferenceError: socket is not defined
I tested this without custom namespaces and the same issue arose. The server side is just fine as I can emit events.
The Client code looks like this:
Client
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.js"></script>
<script>
var socketOptions = {};
socketOptions.transports = ['polling'];
var client = new PlayClient();
var playSocket = io.connect('http://localhost:8044/clients', socketOptions);
playSocket.on('connect', function(socket) {
console.clear();
console.info("CLIENT: Connected.");
socket.on("client:change scene", function(newSceneId) {
console.log(newSceneId);
client.changeScene(newSceneId);
});
});
</script>
It looks like I just overwrote the socket. So, basic troubleshooting led me to this answer leading me to confirm that. However, passing (data) or something else instead still leaves socket undefined but with the console declaring: TypeError: undefined.
If I change .on('connect') to .on('connection'), the socket is no longer overwritten but fails to connect or receive any emitted events because the socket.io client does not understand the 'connection' event.
Any help with this is much appreciated, as I seem to be caught in a circular rut.
you seem to be confusing server side and client side events; they are pretty different. each client object can only be connected to a single server, while the server can receive many connections
maybe try something like:
var playSocket = io.connect('http://localhost:8044/clients', socketOptions);
playSocket.on('connect', function() {
console.clear();
console.info("CLIENT: Connected.");
}
playSocket.on("client:change scene", function(newSceneId) {
console.log(newSceneId);
client.changeScene(newSceneId);
});
Related
I'm trying to use socket.io to connect to this websocket api:
https://www.cryptocompare.com/api/#-api-web-socket-
(wss://streamer.cryptocompare.com)
I guess im not really understanding socket.io very much.
I created a blank html document:
<!doctype html>
<html lang="en">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.1.1/socket.io.slim.js"></script>
</head>
<body>
<div id="data-show">
</div>
<button id="connect-sock">Connect</button>
<button id="disconnect-sock">DISConnect</button>
</body>
<script src="index.js"></script>
</html>
index.js:
var socket = io('wss://streamer.cryptocompare.com')
console.log('connected')
var btn = document.getElementById('connect-sock')
var btn2 = document.getElementById('disconnect-sock')
var show = document.getElementById('data-show')
//I also tried adding an event listener to a button so when i clicked it, it would do this:
socket.emit('SubAdd', { subs: ['0~Poloniex~BTC~USD'] } )
//Same result of nothing.
socket.on('SubAdd', function(data){
console.log(data)
})
server.js:
var express = require('express')
var socket = require('socket.io')
var app = express()
var server = app.listen(4000, function(){
console.log("well met")
})
app.use(express.static('public'))
var io = socket(server)
io.on('connection', function(socket){
console.log('well met from socket connection', socket.id)
})
server.js is in a file named 'socket-test'. index.html and index.js are in 'socket-test/public/'
so for some reason, in server.js, socket.id will not log to console. its as if this function is being skipped over. but when i change the address in index.js to http://localhost:4000, i get socket.id in console... not sure whats going on there.
Edit: I rarely get socket id when using the wss://streamer.cryptocompare.com/ , sometimes I do, most of the time i dont. It usually works when I switch to localhost, run the server, stop the server, then switch back to the streamer, but if i reload, i dont get socket.id anymore.
I thought that all I was asking it to do here was emit subs to wss://streamer.cryptocompare then console.log(data) that it returns after emitting the subs.
am I missing something here?
Sorry in advance if its blatantly obvious that I'm missing something. I've only known about socket.io for maybe 3 days now, and only today have I watched a basic tutorial on youtube.
You don't need the Express code because in this case the server you want to talk to is on the cryptocompare server -- not a local server. This is captured in your code when you initialize the io object in the HTML file.
Of course, you could still use Node to talk to the cryptocompare websockets API if you're more comfortable with Node. But then you wouldn't need the in-browser JavaScript. Either way, what you need is to create some kind of client in any runtime that speaks websockets and can talk to the cryptocompare websockets API.
With regard to the code being skipped over -- you're right! It is. socket.io is an event driven WebSockets framework. This means that clients register their interest in certain kinds of events/messages, and when those are triggered special functions known as callbacks are called.
If it helps, you can think of those events like channels in a chat room -- if you're not in the right room, you won't see the messages for that room. So you'll need to know what messages you should be listening for, register your interest in those, and register callback functions for each one.
Thankfully cryptocompare has provided client code examples that should help you get an idea for the kinds of messages you should be listening for.
See here
I'm using socket.io-client to create a socket connection to my locally-running server. See my code below:
// Working example of connecting to a local server that is not SSL protected
var io = require('socket.io-client')
var socket = io.connect('http://localhost:3000', {reconnect: true});
socket.on('connect', function(){ console.log("inside 'connect'") } );
socket.on('connection', function(){ console.log("inside 'connection'") } );
socket.on('event', function(data){ console.log("inside 'event'") } );
socket.on('disconnect', function(){ console.log("inside 'disconnect'") } );
var payload = {email: 'fake#gmail.com', password: 'tester'};
var tokens = {browserId: 'b965e554-b4d2-5d53-fd69-b2ca5483537a'};
socket.emit("publish", {logic:"user", method:"signIn"}, payload, tokens, function(err, creds) {
console.log("inside the socket client emit callback. err: " + err);
console.log("creds: " + creds);
});
Now for my problem. As I stated in the comment at the top of that code, I can connect to my local nodejs server and get the response I expect when I turn off SSL encryption on my server. As soon as I turn SSL on, I stop getting any response at all from the code above. I don't see any message in my server logs or from the command line, where I'm running the code above with node.
My goal is to be able to run the code above, with SSL turned on in my server, and get the same response that I get when SSL is turned off. I've tried a bunch of variations on the code I included above, such as:
connecting to "https://localhost:3000"
connecting to "//localhost:3000"
connecting to "https://localhost:3443" (this is the port I have to connect to when I have the nodejs server running with SSL)
changing {reconnect:true} to {reconnect:true,secure:true}
I'm truly stumped, and I've been doing a bunch of research on the web and on my node server. It's my company's code and I didn't originally implement the SSL components, so I've spent a few hours looking at our code and trying to understand how adding SSL changes everything. I'm also a student and have about 2 years of experience behind me, so I'm good but I'm no expert. Have I said anything above that indicates if my task is impossible to achieve, or if maybe I have just overlooked something? Any leads on things to check out would be appreciated :)
I am trying to seperate logic in my socket.io server but i am experiance some issues.
say for instance i have the following:
io.on('connection', function (socket) {
var fileModule = require('./costum_modules/FileModule.js')(io);
app.use(fileModule);
});
Now inside the fileModule i have the following code:
var fileModule = function (socket) {
socket.on('userData', function(msg){
var i = 0;
});
}
module.exports = new fileModule();
Sadly the socket i undefined.
My question is can i do it like this or is it not possible to pass a singleton to another file and make it read from the same object?
You can use other files to break up your logic, but there are a couple issues with your code.
First, I think Hacketo is correct that you don't want to do new fileModule(), just:
module.exports = fileModule;
Second, when call require, you are passing the global socketIO object (io). You should pass it the socket you get in the connection handler. E.g.
require('./costum_modules/FileModule.js')(socket);
I think that will work to move some of your socket.io message handling code into a module. Now your socket will respond to userData messages from a client. However, unless you have some custom application, I don't think app.use is going to do what you expect. You can't hook web socket handlers into an Express/Restify/Connect/Whatever middleware chain. But you could write a middleware that sends a message to your socket server.
If you are just trying to share the session between your app and socket server, try this SO answer.
I'm able to send socket.io connections from my extension to my server, but I cannot hear emits from my server inside my extension. I've found conflicting answers regarding this question:
Opening a Socket.IO connection in a google chrome extension says this can't be done; and
Cross-domain connection in Socket.IO says it can.
Is there any special configuration I must change in order to accept emits from my socket server?
EDIT:
(Note: I'm using AngularJS, but it shouldn't be relevant to this question)
socketFactory.js:
myApp.factory('socketFactory', function($rootScope) {
var socket = io.connect('//dev.mydomain.com', {'path': '/api/socket'});
return socket;
}
inject.js:
var packetData = { 'some':'data', 'roomId':'123abc' };
socketFactory.emit('room:join', packetData);
...
socketFactory.on('room:update', function (data) {
console.log('Received data from socket server');
console.log(data)
}
socket.js (server-side):
socket.on('room:join', function ( data ) {
// Setting socketId to detect disconnect
data.user.socketId = socket.id;
socket.join( data.roomId, function() {
// Some code ...
io.sockets.to(data.roomId).emit('room:update', {'some':'data', 'roomId': '123abc'});
}
});
That's the basic setup of my connection. This system works perfectly when I launch the app in non-extension mode (we're making an extension to emulate our webapp), but when in the extension, room:update is never triggered.
EDIT 2:
We did a console.log on the socket object (generated on connect) in socket.js. Inside the headers, it appears the host is dev.mydomain.com, while the referrer is www.othersite.com. Could this be the problem? What does "host" refer to? Host of the socket server, or host of the socket listener? In the latter case, it would make sense it's not reaching www.othersite.com over which we have the extension running.
EDIT 3: ...And it started working out of nowhere. Must be a race condition somewhere. Closing the question as no longer relevant.
It suddenly works. Probably a race condition.
Im trying to set up a node.js server to send messages to the client, which will then display the messages using a jquery notification library, I'm using this notifcation library if anyone's interested: http://needim.github.com/noty/
At the minute I have a postgres database set up with a table which has a a trigger on it to write to a listener.
The trigger is as follows:
CREATE OR REPLACE FUNCTION new_noti() RETURNS trigger AS $$
DECLARE
BEGIN
PERFORM pg_notify('watchers', TG_TABLE_NAME || ',msg,' || NEW.msg );
RETURN new;
END;
$$ LANGUAGE plpgsql;
Then I have a node.js server as follows:
var pg = require ('pg');
var pgConString = "pg://aydin:password#localhost/test"
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, url = require('url')
app.listen(8080);
function handler (request, respsonse) {
var client = new pg.Client(pgConString);
client.connect();
client.query('LISTEN "watchers"');
client.on('notification', function(msg) {
console.log(msg.payload);
sendMessage(msg.payload);
});
}
function sendMessage(message) {
io.sockets.emit('notification', {'message': message});
}
Then I have some client code as follows:
<script type="text/javascript">
var socket = io.connect('http://localhost:8080');
socket.on('notification', function (data) {
console.log(data.message);
newNoty(data);
});
function newNoty(data) {
noty({
"text":data.message,
buttons: [{
type: 'button green',
text: 'Go to'
}],
"theme":"noty_theme_twitter",
"layout":"bottomRight",
"type":"information",
"animateOpen":{
"height":"toggle"
},
"animateClose":{
"height":"toggle"
},
"speed":500,
"timeout":7500,
"closeButton":true,
"closeOnSelfClick":true,
"closeOnSelfOver":false,
"modal":false,
});
}
</script>
This doesn't work, it seems the node.js never receives the postgres notifications, I think this is because I am using the function handler and I'm not actually firing any requests to it from the client code. I'm not sure how to do this and whether it is the correct way?
Is there a function on which can fire on connections and not requests?
And am I even doing it the right way round? should there be a server on the client side which node.js sends messages to? How does it know when a client is available? Any help or pointers to tutorials would be much appreciated. Thankyou.
You're not actually setting up your database connection until the client sends an HTTP request. It looks like that may never happen due to same-origin issues (your client code appears to be coming from somewhere other than the server you've shown).
In any case, you probably want to set up the connection in response to a "connection" event from io.sockets (i.e. move the stuff that's currently in the HTTP request handler there). That's how it "knows when a client is available". Or maybe you should be doing it as part of initialization. Your client-side code seems OK, but it's out of context so it's hard to tell whether it really fits your needs.