I've been doing alot of testing with socketIO and have got stuck with handling situations where my node app is simply offline. The documentation provides no real insight into this issue.
So if i run my website and node app is simply not running, console.log gives:
GET http://[url]:[port]/socket.io/socket.io.js
Uncaught ReferenceError: io is not defined
This is hardly surprising, how ever what i don't understand is how to handle these errors and simply have the script try to attempt a reconnect until it finally does reconnect (if ever).
My script looks like this:
<script src="http://[url]:[port]/socket.io/socket.io.js"></script>
<script>
windows.onload = function()
{
socketio = io.connect("http://[url]:[port]");
socketio.on('connecting', function() {
console.log('trying to connect');
});
socketio.on('connect', function() {
console.log('connected');
});
}
</script>
Is there a way to handle this kind of problem ?
When the server is offline, your initial <script> tag to load the Socket.io client library fails, so you never get the io object in the first place.
To retry, you can add a new <script> tag to load the same URL again and see if it succeeds.
Better yet, copy the socket.io client library to the server hosting your HTML, so that the script will always load. You can then simply handle connection errors from io.connect().
There are a few events that you can bind to.
socket.on("connect_failed", function() {
// Do whatever you wanted to do on failure
});
For a full list of exposed events check here: exposed socket.io events
Edit
Ah, I'm sorry. I misunderstood your question. I thought you wanted to handle when the socket server was offline. If you want to handle not being able to get at the socket.io client script, maybe you could check if socket is null or undefined and handle thought that. Then also fire a setTimeout function to try and load the script asynchronously after a wait period and then check if socket is still undefined or null. Or, as the other answer suggests, pack the socket.io client library with the rest of your HTML page.
Related
I have been trying to create an online game but when I try to use socket.on(...); or socket.emit(...) it comes up with an error like what is socket. I have seen some posts similar to this one and tried all the solutions but none worked. I have already got io.connect(...); working and it works (I assume this means I have properly set up socket.io-client). I just don't see what I am doing wrong. If you need the code you can simply request it though I don't think it was necessary. Thanks.
To use SocketIO on the client-side, first import it via
import * as io from 'socket.io-client';
Then, probably in a constructor, establish a connection to the server's ip and port running the SocketIO server
const socket = io(`172.16.1.3:81`);
Also in the constructor you will likely want to setup a function to be called when the server sends a certain message type:
socket.on("update-player", handlePlayerUpdateFunction);
and
function handlePlayerUpdateFunction(message) {
console.log(`Received message from server: ${message}`);
}
If this client does not receive the message sent from your server, then something is wrong with your server not being set up correctly to listen on the port.
After trying some things and doing some research I found the solution to my problem. Adding in var socket = io.connect(x.x.x.x:3000); my code started functioning and everything was perfect I had already imported socket.io-client trough CDNJS link on the installation guide. I just had to Initialise the variable.
I am using onvif node js module and node-rstp-stream module to convert RSTP stream to img stream which can be used in phonegap(RSTP stream is not supported in phonegap I think).
Here I am using express js, so whenever I send a request to /livestreaming first time it works fine but not next load it tries to create one instance on same port number which creates an issue. Is there way to check if the server is running close on every request and start it again so that we dont the port already in use error. Is there a way better than this please let me know.
Below is the code which I tried.
app.get('/livestreaming', function (req, res) {
if(cam !== null) {
cam.getStreamUri({protocol:'RTSP'}, function(err, stream) {
newsocket = new Stream({
name: 'mysoc',
streamUrl:stream.uri,
wsPort: 8888
});
});
} else {
res.json({"error":"connect to camera"});
}
});
The node-rtsp-stream library does not provide any way to check if the port is already in use, neither any way to close the socket server.
So, from my point of view you have two options:
Try to connect to your socket server port to use if it is available, for example by doing a ping, and only launch a new Stream in case is not.
Since the node-rtsp-stream library is very simple, and I already have practice with it, you can add this code right after your newly created stream:
newsocket.wsServer.on('error', function() {
newsocket.mpeg1Muxer.stream.kill();
});
So, where this came? If you take a look to the library, you will find that the wsServer is your socket server and mpeg1Muxer is the stream open with your camera. Because of the already in use error, the server won't launch, but you should also kill the ffmpeg process. This way, if the server is already running, nothing happend, and if not, it will launch.
This last solution is little bit tricky, but I thing it will work.
Hope it helps
I opened a question here earlier (Socket.io trigger events between two node.js apps?), this was much help, but I am confused out of my mind.
I keep getting object is not a function on my client side script.
A little setup, I have a front end site that is served with express localhost:9200 then I have a back end app localhost:3100 that is also served with express and I am trying to emit events from localhost:9200 to the socket.io server localhost:3100
Client script for website localhost:9200
// I have tried many different ways
var socket = io('http://localhost:3100');
var socket = io('http://localhost');
var socket = io();
EDIT
The issue was with the above of course, because io in the above case for some reason was an object when it should be a function, I came across an old post which mentioned using var socket = io.connect('http://localhost:3100'); connect and that worked, I though it was depreciated or something, I have no clue why the docs don't mention this but it fixed my issue.
All result in object is not a function. I include the client side script like this
// tried some different ways
<script src="http://localhost:3100/socket.io/socket.io.js"></script>
<script src="socket.io/socket.io.js"></script> // this is a 404
I have installed https://github.com/automattic/socket.io-client and on the server for the front end website :9200 I have set it up like.
// tried a couple ways to connect
var socket = require('socket.io-client')('http://localhost:3100');
var socket = require('socket.io-client')('http://localhost');
socket.on('connect', function(){});
socket.on('event', function(data){});
socket.on('disconnect', function(){});
I am confused on how to properly configure this so that I can get my site to emit socket events to my server and visa versa?
Well I figured it out, this is pretty ridiculous but on the client side javascript I needed to add var socket = io.connect('http://localhost:3100'); the io.connect made it work versus var socket = io('http://localhost:3100');
Maybe I missed it but the docs don't say to use io.connect https://github.com/automattic/socket.io-client whatever it works and I am happy, any thoughts on why the docs don't mention this would be great.
The difference is io.connect is pre 1.0 syntax. They changed it for whatever reason. These are the exact kind of fun surprises I have come to expect in socket.io.
I'm building a simple real-time chat app to learn how to use websockets with RoR and I don't think I'm understanding how channels work because they're not doing what I expect. I can successfully send a message to my Rails app using the dispatcher.trigger() method, and use my websocket controller to broadcast a message to all clients that subscribe to the channel. That all works fine. What does NOT work is using a channel (via the channel.trigger() method) to send a message to other clients. The websocket-rails wiki says...
Channel events currently happen outside of the Event Router flow. They
are meant for broadcasting events to a group of connected clients
simultaneously. If you wish to handle events with actions on the
server, trigger the event on the main dispatcher and specify which
controller action should handle it using the Event Router.
If I understand this correctly, I should be able to user the channel.trigger() method to broadcast a message to clients connected to the channel, without the message being routed through my RoR app, but it should still reach the other connected clients. So here's my code...
var dispatcher = new WebSocketRails('localhost:3000/websocket');
var channel = dispatcher.subscribe('channel_name');
channel.bind('channel_message', function(data) {
alert(data.message);
});
$("#send_message_button").click(function() {
obj = {message: "test"};
channel.trigger('channel_message', obj);
});
With the code listed above, I would expect that when I click the button, it sends a channel message using channel.trigger() and the channel_message binding should be executed on all clients, displaying an alert that reads "test". That doesn't happen. I'm using Chrome tools to inspect the websocket traffic and it shows the message being sent...
["channel_message",{"id":113458,"channel":'channel_name',"data":{"message":"test"},"token":"96fd4f51-6321-4309-941f-38110635f86f"}]
...but no message is received. My questions are...
Am I misunderstanding how channel-based websockets work with the websocket-rails gem?
If not, what am I doing wrong?
Thanks in advance for all your wisdom!
I was able to reproduce a working copy based on an off-the-shelf solution from the wiki along with your very own code.
I've packaged the whole thing here. The files you might be interested are home_controller.rb, application.js and home/index.html.erb.
It seems your understanding of channel-based websockets is correct. About the code, make sure to load the websocket javascript files and to enclose your code inside a document.ready. I had the exact same problem you're having without the latter.
//= require websocket_rails/main
$(function() {
// your code here...
});
Let me know if it works. Best Luck!
I'm using the cfwebsocket tag in Coldfusion to create a web socket connection.
I looked at an example from here http://www.sagarganatra.com/2012/03/html5-websockets-in-coldfusion-10.html
and near the end it shows you all the javascript calls you can make on the web socket object.
However, when I try to make any call on it I get an error that it is undefined.
For example I have:
<cfwebsocket name="ws" onMessage="messageHandler" onOpen="openHandler" onClose="closeHandler" onError="errorHandler" subscribeTo="chat" />
and in my javascript i call
alert(ws.isConnectionOpen());
and I get the error in firebug: TypeError: ws is undefined.
Anyone know why I can't call it?
My chat works fine and I can connect and chat properly. I just wanted to close the connection when the chat ended so I was looking into how it's done calling the websocket but I don't know why it's not working.
Note that I am using jQuery and the javascript is wrapped in the document ready.
First, you can't interact with the ws object till it establishes a connection to the server.
There are a couple of ways to handle this scenario. You can use the "onOpen" attribute and have it call a function once the web socket connect has been established.
However, you are probably better off just using the "onMessage" attribute and create a generic listener function that processes all web socket messages from the server.
function messageHandler(msg) {
if (msg.type == 'response' && msg.reqType == 'welcome'){
alert('user connected');
}
}