I've got a node.js server up and running with express and i'm trying to establish a websocket connection using socket.io server-side and chrome 12 client-side. When I try to connect, socket.io outputs a debug message saying "destroying non-socket.io upgrade" and the code in my connection handler doesn't run. Also on the client-side the readyState of my socket is 2 (CLOSING).
[edit]
readyState of the socket changed from 0 to 2
Make sure you're inserting the socket.io.js file into your client code and using it. If you try to create your own websocket on the client-side, you'll probably run into problems.
Do something like this for your server:
var app = require('express').createServer()
, io = require('socket.io').listen(app);
app.listen(80);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
io.sockets.on('connection', function (socket) {
socket.emit('news', { hello: 'world' });
socket.on('my other event', function (data) {
console.log(data);
});
});
and something like this for the HTML file you're serving:
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.on('news', function (data) {
console.log(data);
socket.emit('my other event', { my: 'data' });
});
</script>
Make sure you're serving /socket.io/socket.io.js from your webserver dir. Then all you have to do is watch your console log in the web browser's Developer environment from the Options or with Firebug when you go to the page.
Related
I'm trying some things with socket.io on NodeJS and I can't figure out how to trigger the the socket (only) from NodeJS.
Till now I was using socket.io by calling it from the front end but I wonder if is it possible to do the same thing I did on the front end but this time on the nodeJS part(server side).
My guess is it's not possible because is required a kind of connection(I like to call it a TCP connection,but I'm not sure if that's true or not) and without a second participant in the connection the socket won't work.That's my guess.
So what I'm doing now is :
app.js(server file)
...
const ioLib = require('./path/io.js')(io);
...
...
...
path/io.js(socket file)
module.exports = function(io){
io.on('connection', async function(socket) {
console.log('socket talks : a user connected');
...
...
});
module.exports.io = io;
}
And from an file.ejs file I do :
var socket = io("url");
So with this,let's call it schema,I do the following :
When I access that webpage the 'connection' event is triggered in the sockets.
My question is,and I'm trying to formulate it as simple as I can :
How can I do the same but without a webpage?Is it possible to trigger the sockets inside the NodeJS?
What do you think?
It is possible to connect a Socket.IO server from a stand alone Node.js application (does not really matter where it runs) rather than a web front-end, accessed via a web browser. In order to achieve this, you should use socket.io-client. An example client usage might be as follows:
// Node.js app: client.js
const io = require('socket.io-client');
const socket = io.connect('http://SERVER_IP:SERVER_PORT', {
reconnect: true
});
socket.on('connect', function (socket) {
console.log('Connected to the server!');
});
socket.emit('connected', 'Hi from the client side!');
In this case, your server side application should include something as follows:
// Node.js app: server.js
io.on('connection', function(socket) {
console.log('socket talks: a user connected');
// Print the message that comes from the socket client
socket.on('connected', function (msg) {
console.log(msg);
});
});
As you can see above, fundamentally, the architecture remains the same as server-client. Now, let's go one step further and put all those codes in a single js file, and see how it works:
// server/client together: crazy-socketapp.js
const io_server = require('socket.io').listen(3030);
io_server.sockets.on('connection', function (socket) {
console.log('A client is connected!');
socket.on('connected', function (msg) {
console.log(msg);
});
});
const io_client = require('socket.io-client');
const socket = io_client.connect('http://localhost:3030', {
reconnect: true
});
socket.on('connect', function (socket) {
console.log('Connected to the server!');
});
socket.emit('connected', 'Hi from the client side! ');
The output of the app:
> A client is connected!
> Connected to the server!
> Hi from the client side!
Hope this helps!
I can't figure out why my socket.io server isn't receiving messages from the client. Here is my server JS file:
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('bid', function(msg){
console.log('received:' + msg);
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
And here is the client-side code:
$(function () {
var socket = io(':3000/socket.io/socket.io.js');
$('#bid-form').on('submit',function(){
socket.emit('bid', 'test');
console.log('emit');
return false;
});
});
When I open and close the browser page I see the "user connected" and "user disconnected" messages on the server console so I know it's making the connection.
When I submit the form I see the "emit" message in the browser console so I know the form submit event is firing but I'm not receiving the test message on the server. Nothing seems to happen on the client or sever end, it seems like the "socket.emit" function isn't doing anything.
What am I doing wrong?
My assumption is that you are running your express server on localhost.
It looks like you're accessing your HTML file directly through file:// unless your client-sided code is hosted by a different web server. But regardless of that, here's how you can connect:
<script src="http://localhost:3000/socket.io/socket.io.js"></script>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script>
$(function () {
var socket = io("http://localhost:3000");
$('#bid-form').on('submit',function(){
socket.emit('bid', 'test');
console.log('emit');
return false;
});
});
</script>
You will need to load the socket.io.js file through the script tag. Then connect to your socket.io server by providing the host of the socket.io server to the io() function.
I am new to nodeJS...and programming. But I have tried to get this bit of code to work and I cannot understand why it does not seem to work. Whats worse is I do not know how to troubleshoot it either. If I use console.log statements, I can see that once I launch the webpage, it DOES connect, but the webpage never gets a message from the nodeJS server and the server never gets a message from the webpage. I am using Chrome browser.
server.js:
var express = require('express'),
app = express(),
server = require('http').createServer(app),
io = require('socket.io').listen(server);
server.listen(80);
app.use(express.static(__dirname + '/public'));
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
var SerialPort = require('serialport');
var portName = process.argv[2];
var sp = new SerialPort(portName, {
baudRate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
io.sockets.on('connected', function (socket) {
socket.emit('connected', {
data: 'connected'
});
socket.on('connected', function (data) {
console.log(data);
//Code
console.log('Sending Packet. Contents:');
sp.write(packet);
console.log(packet);
console.log('Packet Sent');
});
});
I launch it from command prompt on raspbery pi zero w:
sudo node server.js /dev/ttyACM0
The index.html references the interface.js. The top part of interface.js:
$(document).ready(function() {
// Connect to the node.js server. Gets server's local ip.
// Using this method robot can only be connected to on
// local network.
var ip = location.host;
var socket = io.connect(ip); // Connects to server
// Upon establishing a connection to the socket.io server...
socket.on('connected', function (data) {
console.log(data);
// Send out a message to the server
socket.emit('connected', { command: 'nothing' });
});
When I have console.log statements in the interface.js I get them until the socket.on statement.
node -v
v6.4.0
npm -v
5.3.0
npm list socket.io
socket.io#2.0.3
uname -m
armv6l
Edit: Updated messaging commands. Same issue. Also
Well, turns out I have the wrong version of socket.io.js. So. That was a week of learning. Thanks for the help.
My problem is simple I'm actually getting an error 404 when I'm trying to import socket.io on my web page. I'm using
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
to import socket.io.
If I remove this line form my head tag, I'm fine but when it's there, I see in the dev tool the 404 error and my counter is not even working.
I am trying to make a live viewer count for one of my website but I never really use Node.js so this is why I have some trouble. Please forgive me if there is an error in my script.
For the serverside script, the file is called: viewercounter.js and this is the code
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = 8001;
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
app.use(express.static(__dirname + '/public'));
var count = 0
io.on('connection', function(socket) {
count++;
socket.broadcast.emit('userupd', {
numUsers: count
});
console.log(count);
socket.on('disconnect', function(){
count--;
socket.broadcast.emit('userupd', {
numUsers: count
});
console.log(count);
});
});
Then I placed the clientside script directly in my page instead of making a new file, I did not really see the point of it. Anyway, the file is called: index.php
and the code is at the end of the file just before the end of the body tag and there not other js before the code.
<script type="text/javascript">
$(function() {
var socket = io();
socket.on('userupd', function (data) {
$('.counter').html(data);
});
});
EDIT
By looking more deeper, I've been able to understand that it's a XMLHttpRequest problem. In fact, when the socket.io code that I just imported try to perform xhr.send(this.data) the error appears. Anyone knows how I can solve this ?
https://gyazo.com/53f64081a92b449e157df76c6c570178
EDIT2
After changing the port in the file viewcounter.js. It looks like this:
// Setup basic express server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var io = require('socket.io')(server);
var port = 80;
server.listen(port, function () {
console.log('Server listening at port %d', port);
});
// Routing
app.use(express.static(__dirname + '/public'));
var count = 0
io.on('connection', function(socket) {
count++;
socket.broadcast.emit('userupd', {
numUsers: count
});
console.log('New user: ');
socket.on('disconnect', function(){
count--;
socket.broadcast.emit('userupd', {
numUsers: count
});
console.log('Neg user:');
});
});
If your web page is coming from an Apache web server on port 80 and you want to create a socket.io server in node.js on the same host, then you need to pick a new port for that socket.io server and when you connect to the socket.io server, you need to identify the port you want to connect to because the default will be port 80, but that's not where your socket.io server is.
I'd suggest using port 8001 like you originally had for your socket.io server. Please change your node.js code back to that.
Then, you can change the socket.io code in your page from this:
<script type="text/javascript">
$(function() {
var socket = io();
socket.on('userupd', function (data) {
$('.counter').html(data);
});
});
</script>
to this:
<script type="text/javascript">
$(function() {
var url = window.location.protocol + "//" + window.location.hostname + ":8001";
var socket = io(url, {transports: ['websocket'], upgrade: false});
socket.on('userupd', function (data) {
$('.counter').html(data);
});
});
</script>
This will connect socket.io to the same protocol and host as your web page, but a different port and it will use only a webSocket so you don't run into cross origin issues with socket.io's usual attempt to initiate a connection with Ajax polling.
If your socket.io server is actually on a different host than your Apache server, then you need to put that host in the URL rather than window.location.hostname.
I'm new to node.js and socket.io and tried to connect the server to the client with the example from http://socket.io/#how-to-use. (no localhost)
Server:
var app = require('http').createServer(handler)
, io = require('socket.io').listen(app)
, fs = require('fs')
app.listen(80);
function handler (req, res) {
fs.readFile(__dirname + '/index.html',
function (err, data) {
if (err) {
res.writeHead(500);
return res.end('Error loading index.html'+err);
}
res.writeHead(200);
res.end(data);
});
}
io.sockets.on('connection', function (socket) {
socket.on('message', function(msg){
console.log('Got text: '+msg);
socket.broadcast.send(msg);
});
socket.on('disconnect', function () { });
});
Client:
<html><head><script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
socket.on('connect', function () {
alert('connected.');
socket.on('message', function (msg) {
// my msg
alert('message received: '+msg);
});
socket.send('hi');
});
</script>
</head><body>This is the content :)</body>
</html>
Google Chrome displays in the console:
Unexpected response code: 502
Also, after receiving every message, Chrome adds
GET http://[myServer]/socket.io/1/?t=1352313105809 socket.io.js:1659
Socket.handshake socket.io.js:1659
Socket.connect socket.io.js:1699
maybeReconnect
to the console.
Wheres the problem?
The examples from the How-To page all use port 80, which is common for serving websites.
However, you use port 8080 in your example.
Check your web browser's console if it even loads the socket.io script.
You may need to provide http://localhost:8080/socket.io/socket.io.js as explicit url and connect with io.connect('http://localhost:8080');
If the above does not work, please share some insight on what port your web server runs on.
There is no code to actually handle any incoming messages server-side in your (updated) example.
`socket.on('message', function(msg){
console.log('Got text: '+msg);
socket.send(msg);
});
should at the very least send the message back to the client - your alert is only triggered when the client receives a message. Does the node.js console output any incoming or sent messages? A few lines of my node.js console look like the following upon connecting.
debug - client authorized
info - handshake authorized ...
debug - setting request GET /socket.io/1/...
debug - set heartbeat interval for client ...
debug - client authorized for
debug - websocket writing 1::
debug - sending data ack packet