JS + Socket.io + Heroku Problems - Socket.id problem - javascript

Solution
Change
var server = app.listen(3000);
To
var server = app.listen(process.env.PORT || 5000);
I want to deploy an game made with JavaScript on Heroku.
Here's my server:
var express = require('express');
var app = express();
var server = app.listen(3000);
var socket = require('socket.io');
var io = socket(server);
app.use(express.static('public'));
var connectedPlayers = {};
console.log("Server is running!");
io.on('connection',
function (socket) {
socket.on('newPlayer',
function (data) {
console.log("New player connected - ID: " + data.id);
connectedPlayers[socket.id] = {
idOnline: socket.id,
idOffline: data.id,
x: data.w,
y: data.h
};
socket.emit('allPlayers', connectedPlayers);
socket.broadcast.emit('newPlayer', connectedPlayers[socket.id]);
});
socket.on('move',
function (data) {
connectedPlayers[socket.id].x = data.x;
connectedPlayers[socket.id].y = data.y;
socket.broadcast.emit('move', connectedPlayers[socket.id]);
});
socket.on('message',
function (data) {
message = {
name: data.name,
message: data.message,
messageId: generateId()
};
socket.broadcast.emit('message', message);
});
socket.on('emote',
function (data) {
message = {
emote: data.emote,
id: socket.id
}
socket.broadcast.emit('emote', message);
});
socket.on('disconnect', function () {
delete connectedPlayers[socket.id];
io.emit('remove', socket.id);
});
});
This work's fine locally, but when I deploy to heroku I get this error message:
2018-11-23T21:04:18.009491+00:00 app[web.1]: /app/server.js:33
2018-11-23T21:04:18.009512+00:00 app[web.1]: connectedPlayers[socket.id].x = data.x;
2018-11-23T21:04:18.009514+00:00 app[web.1]: ^
2018-11-23T21:04:18.009516+00:00 app[web.1]:
2018-11-23T21:04:18.009518+00:00 app[web.1]: TypeError: Cannot set property 'x' of undefined
I understand that heroku is not recognizing the "connectedPlayers" array at that index, but how this can work properly locally?
What's wrong with the socket.id property?
PS.: the socket.id it's sended by the client, but I think that's generated after a client establish an connection with the server right?

After looking for a lot of solutions, I was trying crazy things to insert the:
process.env.PORT || 5000
on the server.listen.
As you can see in the code of the question, I've posted an out of date code, with the following line (my first try):
var server = app.listen(3000);
The solution was simplier than I thought, just changing the above line of code to:
var server = app.listen(process.env.PORT || 5000);

Related

How to make a socket.io connection between two different interfaces?

I'm actually trying to make a real-time connection between two different apps. I've found a bunch of tutorials about how to make a chat using socket.io, but that doesn't really help me since it's just the same app duplicated in multiple windows.
I'm making a pick & ban overlay for League of Legends in local development. My first thought was to display the empty overlay on one hand and create an interface to manually update it on the other hand. Socket.io seems to be the right thing to use in my case since it can provide new data without having to reload the component.
This is what I wrote in both apps :
const express = require('express');
const socket = require('socket.io');
// App setup
const app = express();
const server = app.listen(4200, function () {
console.log('Listening to requests on port 4200')
});
// Static files
app.use(express.static('public'));
// Socket setup
const io = socket(server);
io.on('connection', function (socket) {
console.log('Made socket connection', socket.id);
socket.on('change', function (data) {
io.sockets.emit('change', data);
});
});
But I fail to connect them as they have to listen to the same port. What am I doing wrong?
(Forgive my bad English and lack of syntax, I'm doing my best here. :p)
I am certainly not an expert on network programming, but as far as I know you need to have one listening app (backend) and another one to connect to it (client). And you define what happens with all the data (messages) that backend recieves (for example sending the messages it recieves to all the clients in the same chat room).
If I am correct to assume you are trying to connect two listening apps?
simple google search of "nodejs socket server client example" revealed this https://www.dev2qa.com/node-js-tcp-socket-client-server-example/ might wanna take your research in this direction
u can try something like this way
var express = require('express');
var socket = require('socket.io');
// App setup
var app = express();
var server = app.listen(8080, () => {
console.log('App started')
})
// Static file
app.use(express.static('public'))
// Socket SetUp
var io = socket(server);
io.on('connection', socket => {
console.log('made the connection')
socket.on('chat',data => {
io.sockets.emit('chat',data)
});
socket.on('typing',data => {
socket.broadcast.emit('typing',data);
});
})
create another file and
var socket = io.connect('http://localhost:8080')
// Elenment
var message = document.getElementById('message');
handle = document.getElementById('handle');
btn = document.getElementById('send');
output = document.getElementById('output');
feedback = document.getElementById('feedback');
// Emit Events
btn.addEventListener('click', () => {
socket.emit('chat', {
message: message.value,
handle: handle.value
})
})
message.addEventListener('keypress', () => {
socket.emit('typing', handle.value)
})
socket.on('chat',data => {
feedback.innerHTML = '';
output.innerHTML += '<p><strong>' + data.handle +': </strong>' +
data.message + '</p>'
})
socket.on('typing', data => {
feedback.innerHTML = '<p><emp>' + data + ' is typing a message... </emp></p>'
})
details are given here node socket chat app
Ok, figured it out. Here's how it works using express and vue together :
First, setup socket.io in your express server js file :
const express = require('express')
const { Server } = require('socket.io')
const http = require('http')
const app = express()
const server = http.createServer(app)
const io = new Server(server, {
cors: {
origin: '*',
methods: ['GET', 'POST', 'REMOVE']
}
})
const PORT = process.env.PORT || 8080
io.on('connection', (socket) => {
console.log('New socket user')
socket.on('SEND_MESSAGE', data => {
console.log('received message in back')
io.emit('MESSAGE', data)
})
})
server.listen(PORT, () => { console.log(`Server started on port : ${PORT}`)})
As you can see we received from the client "SEND_MESSAGE" and we trigger MESSAGE from the server to forward the information to all the clients. The point I was missing is that we bind SEND_MESSAGE on the socked created from the connection but we emit from the io server.
Now you vue part :
import io from 'socket.io-client'
export default {
data() {
return {
messages: [],
inputMessage: null,
socket: io('http://localhost:8080')
}
},
mounted() {
this.socket.on('MESSAGE', data => {
this.messages.push(data)
})
},
methods: {
sendMessage() {
const message = {
senderID: this.myID,
message: this.inputMessage,
sendAt: new Date()
}
this.socket.emit('SEND_MESSAGE', message)
this.inputMessage = null
},
},
}

socket.io SSL / HTTPS gives 404 Error on Client / Cannot connect to server

my chat server was working fine on http but now im using letsencrypt and the client returns ERROR 404 in Chrome console when trying to recieve socket.io.js
In the following code samples I replaced my real domain with mydomain.de
Server is running without error:
var app = require('express')();
var fs = require('fs');
var https = require('https');
var io = require('socket.io')(https);
var mysql = require('mysql');
var options = {
key: fs.readFileSync('/etc/letsencrypt/live/mydomain.de/privkey.pem'),
cert: fs.readFileSync('/etc/letsencrypt/live/mydomain.de/cert.pem'),
ca: fs.readFileSync('/etc/letsencrypt/live/mydomain.de/chain.pem')
};
var serverPort = 8888;
var server = https.createServer(options, app);
io.on('connection', function(socket){
console.log('a user connected');
socket.on('join room', function (data) {
socket.join(data.room);
console.log('user' + socket.id + ' joined ' + data.room);
});
socket.on('chat message', function(data){
socket.broadcast.to(data.room).emit('chat message', {is_sender: 0, msg: data.msg});
socket.emit('chat message', {is_sender: 1, msg: data.msg});
});
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
server.listen(serverPort, function(){
console.log('listening on *:' + serverPort);
});
The Client side code looks like this:
<script src="https://mydomain.de:8888/socket.io/socket.io.js"></script>
<script>
var socket = io('https://mydomain.de:8888');
</script>
Seems like the client cannot connect since the server in not logging any connections at all. What am I missing here? Trying to figure it out since hours and read a lot of examples or similar problems but cannot find the mistake I made.

Socket.io client cant connect to server

I have issue related to Socket.io connection to server.
Its working fine on my local, but on dev-server it cant connect.
My backend code look like this:
var app = require('express')();
var server = require('http').Server(app);
var io = require('socket.io')(server);
var redis = require('redis');
server.listen(8080);
console.log('CONNECTED');
io.on('connection', function (socket) {
var handshake = socket.handshake;
console.log(handshake);
console.log("new client connected");
var redisClient = redis.createClient();
redisClient.subscribe('notification');
redisClient.subscribe('rate');
redisClient.on("message", function(channel, message) {
console.log("New message: " + message + ". In channel: " + channel);
socket.emit(channel, message);
});
socket.on('disconnect', function() {
redisClient.quit();
});
});
And my client part like this:
var socket = io.connect('http://localhost:8080');
socket.on('notification', function (data) { console.log(data) }
The error that im facing is when socket.io client tries to send to URL "http://localhost:8080/socket.io/?EIO=3&transport=polling&t=MD_W4lE" request and its failing, with error ERR_CONNECTION_REFUSED. The node server is runing i tested and also tried to change localhost to 127.0.0.1 and ipv4 address, i didnt helped.

Socket IO server neither emits nor receive any message to/from client : MEAN with ionic

I am writing a chat app using MEAN stack, however i got stuck while implementing them. The server is not getting any kind of update from client neither it sends any thing to client. I guess there is some error in server, but could not figure it out any where.
The server.js file is :-
(function (exports, require, module, __filename, __dirname) {
var express = require('express'),
neo4j = require('node-neo4j'),
bodyParser = require('body-parser'),
app = express();
//socket io integration
var io = require('socket.io')(3000);
var clients = [];
app.get('/', function (req, res) {
res.sendfile('./index.html');
});
io.on('connection', function (socket)
{
console.log("Server : Connected to Socket IO");
console.info('New client connected (id=' + socket.id + ').');
socket.on('user enter',function(user_name){
clients.push({id:socket.id,userName:user_name});
len=clients.length;
io.emit('user entrance',clients,clients[len-1].id);
});
socket.on('send msg',function(data){
socket.broadcast.to(data.id).emit('get msg',{msg:data.msg,id:data.id,name:data.name});
});
socket.on('disconnect', function(data){
console.log("user disconnected :" +data.id);
})
});
app.use(require("express").static('data'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.set('port', process.env.PORT || 5000);
app.listen(app.get('port'), function () {
applogger.info('Express server listening on port ' + app.get('port'));
});
});
The client side code (chatController.js) is -
angular.module('myApp')
.controller('ChatCtrl',function($rootScope, $scope, $stateParams,socket,$ionicScrollDelegate,$timeout) {
$scope.userName = $scope.user.name;
socket.on('connect',function()
{
console.log("from userListCtrl : "+ JSON.stringify($rootScope.selectedUser));
$scope.selected_id=$rootScope.selectedUser;
});
socket.emit('user enter',$scope.userName);
socket.on('user entrance',function(data,my_id){
//checking the user id
if($scope.my_id==null){
$scope.my_id=my_id;
}
$scope.user_show=data;
});
$scope.send_msg = function($event){
var keyCode = $event.which || $event.keyCode;
if($scope.selected_id==$scope.my_id){
alert("You can't send msg to your self.");
}else{
if (keyCode === 13) {
var data={
id:$scope.selected_id,
msg:$scope.msg_text,
name:$scope.userName
};
$scope.msg_text='';
socket.emit('send msg',data);
}
}
};
//Getting the messages from server.
socket.on('get msg',function(data){
$scope.msgs=data;
$scope.is_msg_show=true;
addMessage();
});
// function of push messages to an array.
The UI part is very clean, it's user list on which you can click and it will open a chat window where these two user can chat personally. Every thing is happening in client side (such as the user details, msg content etc) except sending the msg to server and getting response from them.
I am stuck in this.

Socket.io on Cloud 9 IDE - warn: error raised: Error: listen EACCES

I am developing in the Cloud 9 IDE.
This is the error I am receiving:
warn: error raised: Error: listen EACCES
I am using the Port that Cloud 9 specifies to use in my code for listen: process.env.PORT
Here is my code:
//app.js Socket IO Test
var express = require("express"),
redis = require('socket.io/node_modules/redis'),
io = require('socket.io').listen(app);
var app = express();
var redisPort = [CENSORED]
, hostname = [CENSORED]
, password = [CENSORED]
, db = 1;
var pub = redis.createClient(redisPort, hostname);
var sub = redis.createClient(redisPort, hostname);
var store = redis.createClient(redisPort, hostname);
pub.auth(password, function(){console.log("adentro! pub")});
sub.auth(password, function(){console.log("adentro! sub")});
store.auth(password, function(){console.log("adentro! store")});
io.configure( function(){
io.enable('browser client minification'); // send minified client
io.enable('browser client etag'); // apply etag caching logic based on version number
io.enable('browser client gzip'); // gzip the file
io.set('log level', 1); // reduce logging
io.set('transports', [ // enable all transports (optional if you want flashsocket)
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
var RedisStore = require('socket.io/lib/stores/redis');
io.set('store', new RedisStore({redisPub:pub, redisSub:sub, redisClient:store}));
});
app.listen(process.env.PORT);
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html');
});
var buffer = [];
io.sockets.on('connection', function(client){
var Room = "";
client.on("setNickAndRoom", function(nick, fn){
fn({msg : "Hello " + nick.nick});
client.join(nick.room);
Room = nick.room;
client.broadcast.to(Room).json.send({ msg: "Se conecto al room: " + nick.room, nick : nick });
});
client.on('message', function(message, fn){
var msg = message; //{ message: [client.sessionId, message] };
buffer.push(msg);
if (buffer.length > 15)
buffer.shift();
client.broadcast.to(Room).json.send(msg);
fn(msg);
});
client.on('disconnect', function(){
client.broadcast.to(Room).json.send({ msg: "Se desconecto"});
});
});
I'm not sure why I'm getting this error while using the port suggested by Cloud 9.
Thanks in advance!
Don't you want to create app = express() before making the socket listen to it ?

Categories

Resources