I'm currently trying to have an angular2 frontend communicating with a node.js backend with socket.io.
The point is, I get the client connected to the server, but after that, no socket call can be successfully passed between them.
Here is a simple piece a code for the server :
var app = require('express')();
var http = require('http');
var server = http.createServer(app);
var io = require('socket.io').listen(server);
io.on('connection', function() {
io.emit('update');
console.log('Connected');
});
io.on('updated', function() {
io.emit('update');
console.log('Updated');
});
server.listen(5000, function() {
console.log('Listening on 5000');
});
... and for the component :
import { Component } from '#angular/core';
import * as io from 'socket.io-client';
#Component({
selector: 'main-app',
template: `
<div>
<button (click)="foo()"
style='padding:20px; background:red; color:white'>
click me
</button>
</div>
`
})
export class AppComponent {
title = 'bar';
socket = null;
constructor() {
let self = this;
self.socket = io.connect('http://mysuperwebsite:5000', {
transports : ["websocket"]
});
self.socket.on('update', function(data) {
console.log(data);
});
}
foo() {
let self = this;
self.socket.emit('updated', {});
}
}
I can't get what is wrong, I guess you will ;)
Thanks for your help !
EDIT : Finally, the problem seemed to come from the lack of second parameter in io.emit(). Now it works, thanks you very much :)
Instead of debugging your code, I'll post you an example that works and you can go from there:
Socket.IO Server
Socket.IO server example using Express.js:
var path = require('path');
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', (req, res) => {
console.error('express connection');
res.sendFile(path.join(__dirname, 'si.html'));
});
io.on('connection', s => {
console.error('socket.io connection');
for (var t = 0; t < 3; t++)
setTimeout(() => s.emit('message', 'message from server'), 1000*t);
});
http.listen(3002, () => console.error('listening on http://localhost:3002/'));
console.error('socket.io example');
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.js
Socket.IO Client
Socket.IO client example using vanilla JavaScript:
var l = document.getElementById('l');
var log = function (m) {
var i = document.createElement('li');
i.innerText = new Date().toISOString()+' '+m;
l.appendChild(i);
}
log('opening socket.io connection');
var s = io();
s.on('connect_error', function (m) { log("error"); });
s.on('connect', function (m) { log("socket.io connection open"); });
s.on('message', function (m) { log(m); });
Source: https://github.com/rsp/node-websocket-vs-socket.io/blob/master/si.html
That example can be installed from npm or downloaded from GitHub. It's as simple as it gets and it's known to work so you can have a working backend part to test your frontend with.
It was written for this answer - you can find mush more info there.
Your server setup seems to be incorrect.
Try this:
io.on('connection', function(socket) {
socket.emit('update');
console.log('Connected');
socket.on('updated', function() {
socket.emit('update');
console.log('Updated');
});
});
Related
I'm trying to create a webtracker to track what pages my users are seeing and how much time they are spending at each page, at the end they will make a registration and i will associate their navigation with the created user.
I want to use node because i can see when the user connect to the url and disconnect to calculate the time, i have tried that with pure javascript but i can see when the user leaves the page only on Chrome.
I have already managed to create some of what i need using the socket.io lib but i can't find a way to use it without creating an html page. What i need is to create something like google analytics where i will only incorporate the script. Is it possible?
I have managed to figure it out so i will post it to help others with the same problem:
Server
let socket = require('socket.io');
let http = require('http');
let serveStatic = require('serve-static');
let finalhandler = require('finalhandler');
var port = process.env.PORT || 1337;
let serve = serveStatic(__dirname, { 'index': ['client.js'] });
let server = http.createServer(function (req, res) {
serve(req, res, finalhandler(req, res));
});
let io = socket(server);
server.listen(port);
io.on('connection', client => {
console.log('new user connected!', client.id);
client.on('hello', data => {
console.log('data: ', data);
});
client.on('disconnect', () => {
console.log('user disconnected', client.id);
});
});
Client
(function (plugin) {
plugin.socket = null;
function loadDependencies() {
head.js(
{ socket: 'https://cdn.socket.io/socket.io-1.4.5.js' }
);
head.ready('socket', function() {
plugin.socket = io('http://localhost:1337');
setSocketHandlers();
});
}
function setSocketHandlers() {
plugin.socket.on('my-event', function(data){
console.log('called my event');
});
}
plugin.init = () => {
loadDependencies();
}
}(this.WebTracker = this.WebTracker || {}));
WebTracker.init();
I am using Adonis 4.1.0 and Adonis-websocket is only been available for v3. Can anyone tell me workaround for using socket.io with Adonis 4.1.0?
apparently they have been working on this not long ago, it was based on socket.io but because of some issues like memory leaks and others, they decided to use websockets directly instead, check these discussions :
https://github.com/adonisjs/discussion/issues/51
https://forum.adonisjs.com/t/integrating-socket-io-with-adonis-4/519
have you tried using socket.io without relying on Adonis ? ,
something like :
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('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
But you should be able to do this with Adonis by now according to : https://github.com/adonisjs/adonis-websocket-protocol
Example :
const filereader = require('simple-filereader')
const msgpack = require('msgpack-lite')
const packets = require('#adonisjs/websocket-packets')
const client = new WebSocket('ws://localhost:3000/adonis-ws')
client.onopen = function () {
// TCP connection created
}
client.onerror = function () {
// TCP connection error
}
client.onmessage = function (message) {
filereader(message, function (error, payload) {
const packet = msgpack.decode(payload)
handlePacket(packet)
})
}
function handlePacket (packet) {
if (packets.isOpenPacket(packet)) {
console.log('Server ack connection. Make channel subscriptions now')
}
if (packets.isJoinAck(packet)) {
console.log('subscription created for %s', packet.d.topic)
}
}
check this for broadcast examples using WS : https://github.com/websockets/ws#broadcast-example
Create start/socket.js file and paste following code inside it.
const Server = use('Server')
const io = use('socket.io')(Server.getInstance())
io.on('connection', function (socket) {
console.log(socket.id)
})
From Virk Himself in this forum:https://forum.adonisjs.com/t/integrating-socket-io-with-adonis-4/519
create a standalone socket io configuration file in start/socket.js
const io = require('socket.io')();
io.listen(3000);
io.on('connection', function (socket) {
console.log(socket.id)
})
to start your socket io server you can configure your server.js as below
new Ignitor(require('#adonisjs/fold'))
.appRoot(__dirname)
.preLoad('start/socket') //path of socket.js
.fireHttpServer()
.catch(console.error)
now when you start your server then it will start along with socket io
I am using SocketIo with Nodejs, Express server and MongoDB, I followed the documentation . it works fine when connecting multiple clients they can send messages to each other without any problem . when I made an Http request, I cannot connect any new clients and get this error.
socket.io.js:7370 WebSocket connection to
'ws://localhost:28232/socket.io/?userId=userAmr&EIO=3&transport=websocket&sid=wNTTgrUD-PSeNaIcAAAF'
failed: Error during WebSocket handshake: Unexpected response code:
400
the other connected users before the Http request can continue sending messages without any problem.
I debugged the Socket library and found the client socket request go to connect function then fire errorCode:1
This this my code
/**
* Create Express server.
*/
const app = express();
// API endpoint
app.get('/api/test',(req,res)=>{
res.status(200).send({test:"test"});
});
/**
* Init socket
*/
// the following line not working too
// const server = require('http').createServer(app);
const server = require('http').Server(app);
const io = require('socket.io')(server);
io.on('connection', (socket) => {
// emit message to group
socket.on('emitMessage', (data) => {
io.emit('emitMessage', data);
});
});
The Client side code
import { Injectable } from '#angular/core';
import * as io from "socket.io-client/dist/socket.io.js"
import { BehaviorSubject } from 'rxjs';
#Injectable()
export class AppSocketService {
private url = 'http://localhost:28232';
private socket;
constructor() {
}
connect(){
this.socket = io(this.url,{
query:{userid:"123"},
forceNew:true,
'force new connection': true,
autoConnect: true,
reconnectionDelay: 1000,
timeout: 100000,
reconnectionDelayMax: 5000,});
this.socket.on('connect', () => {
console.log("connect",{"socketId":this.socket.id});
this.startListening();
});
}
startListening(){
this.socket.on('emitMessage', (data) => {
console.log(data);
});
}
emitMessage(message){
this.socket.emit('emitMessage', {message});
}
}
Client version:"socket.io-client": "^1.7.3"
Server version: "socket.io": "^1.7.3"
i found the problem, the package express-status-monitor making this wrong behavior .
try to remove it, and it will work perfectly
// comment these lines, as they making the issue
// const expressStatusMonitor = require('express-status-monitor');
// app.use(expressStatusMonitor());
The final code:
let app = require('express')();
// these two lines were making the problem, please comment them. if you want to reproduce the problem enable them again
// const expressStatusMonitor = require('express-status-monitor');
// app.use(expressStatusMonitor());
let http = require('http').Server(app);
let io = require('socket.io')(http);
let port = process.env.PORT || 3000;
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
app.get('/api/v0/availabilities',(req,res)=>{
res.status(200).send({test:"test"});
});
io.on('connection', (socket) => {
// emit message to group
socket.on('emitMessage', (data) => {
io.emit('emitMessage', data);
});
});
http.listen(port, function(){
console.log('listening on *:' + port);
});
I have a uWebSockets server as it seems to be a lot more performance friendly than socket.io servers.
So I have a server and its connected fine and after some trouble I got the index.html client side to connect, but now I'm not able to push events to the server from the client side. What am I doing wrong?
var WebSocketServer = require('uws').Server,
express = require('express'),
path = require('path'),
app = express(),
server = require('http').createServer(),
createEngine = require('node-twig').createEngine;
var wss = new WebSocketServer({server: server});
wss.on('connection', function (ws) {
ws.on('join', function (value) {
console.log('SOMEONE JUST JOINED');
});
ws.on('close', function () {
//console.log('stopping client interval');
clearInterval(id);
});
});
server.on('request', app);
server.listen(8080, function () {
console.log('Listening on http://localhost:8080');
});
index.html
<script>
var host = window.document.location.host.replace(/:.*/, '');
var server = new WebSocket('ws://' + host + ':8080');
server.onmessage = function (event) {
updateStats(JSON.parse(event.data));
};
server.onopen = function (event) {
server.send("Here's some text that the server is urgently awaiting!");
server.send('join');
};
function something() {
console.log('WORKED');
server.send('join');
}
</script>
You don't have an event listener setup on the server side that does receive and react on the message. Like
ws.on('message', function (msg) {
// Do something with the message received from the client
});
I'm trying to restart a socket.io server. I start the server and get a welcome message for new connections, but when I close and restart the server I get no further welcome message.
Hopefully I'm missing something simple :\
var http = require('http').Server
var socketIO = require('socket.io')
var socketIOClient = require('socket.io-client')
var port = 3000
var url = 'ws://localhost:' + port
function newServer(serverName, cb)
{
var server = http().listen(port, function()
{
console.log(serverName, 'listening')
var io = socketIO(server)
var clientSocket = socketIOClient(url,
{ reconnection: false })
clientSocket.on('connect', function()
{
// never get 'two connect'
console.log(serverName, 'connect')
io.close()
})
clientSocket.on('disconnect', function()
{
console.log(serverName, 'disconnect')
cb()
})
})
}
function startServerOne(cb)
{
newServer('one', cb)
}
function startServerTwo(cb)
{
newServer('two', cb)
}
startServerOne(startServerTwo)
The parameter I was looking for was "forceNew". It's undocumented in socket.io-client documentation.
This seems to force the socket.io-client to create a new manager instead of using the cached one (which I assume is connected to a server that's no longer running).
The option is described on the socket.io blog and can be seen in the code here with a discussion of the issue here
Full working example:
var http = require('http').Server
var socketIO = require('socket.io')
var socketIOClient = require('socket.io-client')
var port = 3000
var url = 'ws://localhost:' + port
function newServer(serverName, cb)
{
var server = http().listen(port, function()
{
console.log(serverName, 'listening')
var io = socketIO(server)
var clientSocket = socketIOClient(url,
{
reconnection: false,
//////////////////////////////
// this forces a new connection!
forceNew: true
//////////////////////////////
})
clientSocket.on('connect', function()
{
// never get 'two connect'
console.log(serverName, 'connect')
io.close()
})
clientSocket.on('disconnect', function()
{
console.log(serverName, 'disconnect')
cb()
})
})
}
function startServerOne(cb)
{
newServer('one', cb)
}
function startServerTwo()
{
newServer('two', function()
{
console.log('high five everyone')
})
}
startServerOne(startServerTwo)
When you restart the server you kill all connections. Clients should actively reconnect.
You should take a look towards auto-reconnect configuration of client sockets