I'm trying to use cookie based sessions, however it'll only work on the local machine, not over the network. If I remove the session related stuff, it will however work just great over the network...
You'll have to forgive the lack of quality code here, I'm just starting out with node/socket etc etc, and finding any clear guides is tough going, so I'm in n00b territory right now. Basically this is so far hacked together from various snippets with about 10% understanding of what I'm actually doing...
The error I see in Chrome is:
socket.io.js:1632GET http://192.168.0.6:8080/socket.io/1/?t=1334431940273 500 (Internal Server Error)
Socket.handshake ------- socket.io.js:1632
Socket.connect ------- socket.io.js:1671
Socket ------- socket.io.js:1530
io.connect ------- socket.io.js:91
(anonymous function) ------- /socket-test/:9
jQuery.extend.ready ------- jquery.js:438
And in the console for the server I see:
debug - served static content /socket.io.js
debug - authorized
warn - handshake error No cookie
My server is:
var express = require('express')
, app = express.createServer()
, io = require('socket.io').listen(app)
, connect = require('express/node_modules/connect')
, parseCookie = connect.utils.parseCookie
, RedisStore = require('connect-redis')(express)
, sessionStore = new RedisStore();
app.listen(8080, '192.168.0.6');
app.configure(function()
{
app.use(express.cookieParser());
app.use(express.session(
{
secret: 'YOURSOOPERSEKRITKEY',
store: sessionStore
}));
});
io.configure(function()
{
io.set('authorization', function(data, callback)
{
if(data.headers.cookie)
{
var cookie = parseCookie(data.headers.cookie);
sessionStore.get(cookie['connect.sid'], function(err, session)
{
if(err || !session)
{
callback('Error', false);
}
else
{
data.session = session;
callback(null, true);
}
});
}
else
{
callback('No cookie', false);
}
});
});
var users_count = 0;
io.sockets.on('connection', function (socket)
{
console.log('New Connection');
var session = socket.handshake.session;
++users_count;
io.sockets.emit('users_count', users_count);
socket.on('something', function(data)
{
io.sockets.emit('doing_something', data['data']);
});
socket.on('disconnect', function()
{
--users_count;
io.sockets.emit('users_count', users_count);
});
});
My page JS is:
jQuery(function($){
var socket = io.connect('http://192.168.0.6', { port: 8080 } );
socket.on('users_count', function(data)
{
$('#client_count').text(data);
});
socket.on('doing_something', function(data)
{
if(data == '')
{
window.setTimeout(function()
{
$('#target').text(data);
}, 3000);
}
else
{
$('#target').text(data);
}
});
$('#textbox').keydown(function()
{
socket.emit('something', { data: 'typing' });
});
$('#textbox').keyup(function()
{
socket.emit('something', { data: '' });
});
});
Check your system clock, if the server and client have different clocks, the cookie may be immediately expiring right after you set it.
Related
I have a two webservers both running https with the same certificates, I have a main shard that the user connects to example.com, they retrieve some data and try to connect to an ip address on the 2nd shard via websocket.
But no matter what I configure I get an Error 1006 on the client side when connecting to the 2nd shard. Firefox devtooling gives me multiple errors - ssl_error_bad_cert_domain, SSL_ERROR_RX_RECORD_TOO_LONG.
The certificates are issued and signed, I was wondering where I should go from here. Thanks :)
SHARD2
const options = {
key: './server.key',
cert: './server.cert'
};
var https = require('https').Server(options);
https.listen(443, function () {
// console.log('Https listening on *: 443');
});
let WebSocket = require('ws');
let socket = new WebSocket.Server({ server:https });
socket.on('connection', function (ws, req) {
ws.on('message', (msgRaw) =>{
});
ws.on('close', function(code, reason) {
});
ws.on('error', function(error) {
console.log(error);
ws.close();
});
});
CLIENT
function connect() {
"use strict";
window.WebSocket = window.WebSocket || window.MozWebSocket;
if (!window.WebSocket) {
alert('Your browser doesn\'t support WebSocket');
return;
}
wss = new WebSocket('wss://123.123.123.120/:443');
wss.onmessage = function(event) {
};
wss.onerror = function(event) {
console.log(`wss error: ${JSON.stringify(event)}`);
};
wss.onclose = function(event) {
};
}
Useful sys diagram?
I'm new to node
I have a PHP/Laravel cms and I have a simple Nodejs game server which is basically a loop generating some numbers
I connect my PHP backend to Nodejs via Socketio and use Socketio-JWT to identify the user
my client side (php/laravel)
PHP
$userToken = JWTAuth::customClaims(['userid' => Auth::user()->id, 'name' => Auth::user()->name, 'avatar' => asset_url('image/avatar-default.png')])->fromUser(Auth::user() );
html/js
var socket = io.connect("http://localhost:666");
socket.on('connect', function () {
socket.emit('authenticate', {token: '{{$userToken}}'});
});
socket.on('authenticated', function () {
console.log('Authenticated');
});
socket.on('unauthorized', function (data) {
console.log('Unauthorized, error msg: ' + data.message);
});
my serverside
const _online_users = { };
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
_online_users[socket.decoded_token.userid] = {
name : socket.decoded_token.name ,
avatar : socket.decoded_token.avatar ,
}
io.sockets.emit('update_online_users' , _online_users );
socket.on('disconnect', function() {
console.log(`----- ##disconnect -----`)
});
}) ;
as you can see I have an object called _online_users and I store authenticated users in this object and then I send it to the clients so they know who is online
io.sockets.emit('update_online_users' , _online_users );
here is the problem, when the user gets disconnected
socket.on('disconnect', function() {
console.log(`----- ##disconnect -----`)
});
I have to update my _online_users object and remove disconnected user .... how should I go about this? I was thinking maybe I can store the token itself in the _online_users
_online_users[socket.decoded_token.userid] = {
token : socket.token ,
name : socket.decoded_token.name ,
avatar : socket.decoded_token.avatar ,
}
and when the user gets disconnected I get the disconnected token from the socket and remove the user from an object by that token
of course, this is all theory! I'm not sure if that's the way to go .... first of all, I can't access the token itself from the socket !
or let's say one of the users sends another request to node server, how can I identify the user sending the request?
.on('authenticated', function(socket) {
socket.on('somaction', function() {
console.log(` who is this guy ? `)
});
})
is there anything unique insocket.decoded_token that I can use as id? if so I can store it in the online users send it back and forth when the user requests something
basically I'm lost and appreciate any pointers
You can use a middleware now in the newer versions of socket-io. So you can check if the user is logged in by the jwt token that is sent with the request. If decoded successfully you can assign the user info to the current socket and call next() and go to the event you are listening for. Here is the example provided in the socket-io docs slightly modified for your case.
io.use(function(socket, next) {
const handshakeData = socket.request;
// make sure the handshake data looks good as before
// if error do this:
// next(new Error('not authorized'));
// else decode jwt token here and append the user to the socket.request
// and call next
// pseudo code here
const {
authorization
} = handshakeData.header
let token;
if (authorization && authorization.split(" ")[0] === "Bearer") {
token = authorization.split(" ")[1]
}
let user = jwt.decode(token, secret);
socket.request.user = user;
next();
});
You are doing well!
Since you are adding socket event handlers in the 'authenticated' handler you still have access to socket.decoded_token.userid.
This should be enough:
const _online_users = {};
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
_online_users[socket.decoded_token.userid] = {
name: socket.decoded_token.name,
avatar: socket.decoded_token.avatar,
};
io.sockets.emit('update_online_users', _online_users);
socket.on('disconnect', function() {
console.log(`----- ##disconnect -----`);
delete _online_users[socket.decoded_token.userid];
io.sockets.emit('update_online_users', _online_users);
});
});
or to be a little more concise:
const _online_users = {};
io.sockets
.on('connection', socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
}))
.on('authenticated', function(socket) {
const { avatar, name, userid } = socket.decoded_token;
_online_users[userid] = { name, avatar };
io.sockets.emit('update_online_users', _online_users);
socket.on('disconnect', function() {
delete _online_users[userid];
io.sockets.emit('update_online_users', _online_users);
});
socket.on('any other event...', function() {
// ... still have access to userid
});
});
Edit: About unauthenticated socket I don't know; doc says nothing. You could try something like:
io.socket.on('connection', socket => {
socket.emit('update_online_users', _online_users);
// I'm afraid this closes the socket if unauthorized, you could check by yourself
socketioJwt.authorize({
secret: JWT_SECRET,
timeout: 15000
})(socket);
}).on('authenticated', socket => {
//...
});
Hope this helps.
I am currently building a game using Socket.IO and Javascript. I originally wanted to make a real-time multiplayer game, however, I ran into a problem really quick. I eventually gave up and moved to a turn-based game but the problem still didn't go away.
The problem is that the server (app.js) is not getting emits from the client (game.js). I've tried recreating the project, console.log, and search google to no avail.
App.js
require('./Database');
var express = require('express');
var app = express();
var serv = require('http').Server(app);
app.get('/', function(req, res) {
res.sendFile(__dirname + '/client/index.html');
});
app.use('/client', express.static(__dirname + '/client'));
serv.listen(process.env.PORT || 2000);
console.log("Server started.");
var SOCKET_LIST = {};
var io = require('socket.io')(serv, {});
io.sockets.on('connection', function(socket) {
socket.id = Math.random();
SOCKET_LIST[socket.id] = socket;
socket.on('signIn', function(data) { // {username,password}
Database.isValidPassword(data, function(res) {
if (!res)
return socket.emit('signInResponse', { success: false });
Database.getPlayerProgress(data.username, function (progress) {
socket.emit('signInResponse', {
success: true, username: data.username,
progress: progress
});
})
});
});
socket.on('signUp', function(data) {
Database.isUsernameTaken(data, function(res) {
if (res) {
socket.emit('signUpResponse', { success: false });
} else {
Database.addUser(data, function() {
socket.emit('signUpResponse', { success: true });
});
}
});
});
socket.on('disconnect', function() {
delete SOCKET_LIST[socket.id];
});
socket.on("findMatch", function(data) {
console.log('test'); // ******* Not working ********
});
});
Game.js
var socket = io("127.0.0.1:2000");
function findMatch(data) {
socket.emit("findMatch", { socket: socket });
}
FindMatch() is called from the lobby "Find Match" Button. It is hooked up to an onclick listener.
Thank you. I would appreciate any help.
Edit: The connection, sign In, register, and disconnect emits DO work only custom ones I add later (findMatch for example) don't work
I have been looking into this Socket.io MVC node.js but I'm currently struggling.
It says in the documentation:
Socket.io API's
Since Socket.MVC is just a wrapping mechanism for Socket.io, all of
the same API's can be used using the Socket.MVC module. Please see a
list of all of the API's available by visiting the Socket.io Github
page, or http://socket.io (depending on your version)
My problem is that I cant find a way to emit socket MVC to a room.
socketMVC.to(userid).emit('message', {message:2});
Should work, but it doesn't. Any idea how I can accomplish this?
EDIT:
userid is same as assigned here:
import * as io from 'socket.io-client';
download
oninit:
this.socket = io(this.socketurl);
var privateRoom = socket.request.session.passport.user;
socket.join(privateRoom);
this.socket.on('message', (data) => {
// this.messagesCounter = this.messagesCounter + 1;
alert("OMG?");
});
edit , in server.js
io.on('connection',function(socket) {
console.log('user connected');
OnlineUsers.push(socket);
// socket.join('');
console.log(socket.request.session.passport);
console.log("user is connceted");
socketMVC.init(io, socket, {
debug: true,
filePath: ['./src/routes/sockets.js']
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('add-message',function (message) {
io.emit('message', {type:'new-message', text: message});
});
socket.on('myevent', function(someData) {
console.log("MYEVENT WORKS???????");
});
});
sockets.js
var path = require('path');
module.exports = function (socket) {
var privateRoom = socket.request.session.passport.user;
socket.join(privateRoom);
socket.on('testing', function() {
console.log('GOT SOME SORT OF RESPONSE!!!');
});
};
Replace socketMVC.to by socketMVC.io.to.
I have this code running in
Client side:
$(function(){
var iosocket = io.connect();
iosocket.on('connect', function () {
$('#incomingChatMessages').append($('<li>Connected</li>'));
iosocket.on('message', function(message) {
$('#incomingChatMessages').append($('<li></li>').text(message));
});
iosocket.on('disconnect', function() {
$('#incomingChatMessages').append('<li>Disconnected</li>');
});
});
$('#outgoingChatMessage').keypress(function(event) {
if(event.which == 13) {
event.preventDefault();
iosocket.send($('#outgoingChatMessage').val());
$('#incomingChatMessages').append($('<li></li>').text($('#outgoingChatMessage').val()));
$('#outgoingChatMessage').val('');
}
});
});
Server Side
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'});
res.end(fs.readFileSync(__dirname + '/index.html'));
}).listen(8080, function() {
console.log('Listening at: localhost');
});
socketio.listen(server).on('connection', function (socket) {
socket.on('message', function (msg) {
console.log('Message Received: ', msg);
socket.broadcast.emit('message', msg);
});
});
Question :
How can I include the getUserMedia and other WEBRTC API's to create a simple video application ?
Have you looked at, or found, an opensource code set named webrtc.io. If you look at the example code (in the webrtc.io-demo project), you will find a really good example of how to use the getusermedia and peerconnection API's. This code does implement node.js but websocket.io instead of socket.io. I do not know that much about either, so I am not sure if there exists any compatibility between them.