Nuxt Socket.io is unresponsive without any error - node.js

I'm using nuxt-socket-io along with an Express.js server with socketio as well.
When I start up the client/server, the server-side socket.io connects and console for the server will print "connected").
When I try to connect with nuxt (the client-side part of socket.io), nothing happens. Mounted() is called correctly (the "hm" console log prints out), but the socket never seems to be made. I tried testing this.socket.on('connect-error') and this.socket.on('connect-timeout') for the CLIENT side (the server-side socket.io connects properly), but nothing was ever emitted after about 5 minutes of waiting. The persist: true isn't the issue either; I tried to remove it and had the same issue. I initially didn't have this.socket.open() and had the same problems, so I don't think that line does anything, either.
NuxtJS frontend
mounted() {
console.log("hm");
this.socket = this.$nuxtSocket({
channel: '/profile',
persist: true
})
this.socket.open();
this.socket.on('connection', (socket) => {
console.log("connected")
})
//Listens for the SERVER-EMITTED event 'send'
this.socket.on('send', (message) => {
console.log("client received event!")
console.log(message);
});
},
methods: {
sendMessage() {
// This method IS CALLED correctly with a button (I checked), but the emit is not transmitting
// sends a CLIENT-EMITTED event to the server
this.socket.emit('send-message', {
message: "hey!"
}, (res) => {console.log(res)})
},
nuxt.config.js
io: {
sockets: [{
name: 'main',
default: true,
url: 'http://localhost:3000'
}]
},
My Express Backend (port is 8080)
import express from "express";
import { db } from "./app/config/db.config";
import { authRouter } from "./app/routes/auth.router";
import * as dotenv from "dotenv";
const http = require('http');
const socketio = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = socketio(server, {
cors: {
origin: '*',
methods: ["GET", "POST"]
}
});
// run on connection to socket
io.on('connection', (socket: any) => {
console.log("connected")
})
// listens for the CLIENT-EMITTED event 'send-message'
io.on('send-message', (message: any) => {
console.log(message + "server received!");
// sends a SERVER-EMITTED event "send" to be received by nuxt client
io.emit('send', "message!")
})
server.listen(process.env.PORT, () => {
console.log(`Server is running on port ${process.env.PORT}`);
});
Axios is also running on port 8080, I don't know if that would cause any issues but I don't get any errors when I try to run my whole program (which includes login/registration with axios).
Anyone know why my events aren't transmitting? Thank you!

In your server code, you're adding your 'send-message' event listener to the io object, which is your main socket.io Server instance. However, event listeners should be added to the socket object you get from the connection event. Something like:
// A new connection comes in
io.on('connection', (socket: Socket) => {
// Now we listen for the event that comes from this particular socket
socket.on('send-message', (message: any) => {
// You also use the Socket instance to send events back to clients, not to the `io` Server.
socket.emit('send', "message!");
});
});
The Socket instance docs have more info on what you can do with these sockets.

Related

Connect to a third party server (twelvedata) from my own express server through web socket connection string

I want to connect to the twelevedata server through its provided socket connection to receive information.
import * as dotenv from 'dotenv'
import WebSocket from 'ws';
import express from 'express'
const app = express();
//setting up env
dotenv.config()
// setting up the websocket
const ws = new WebSocket(`wss://ws.twelvedata.com/v1/quotes/price?apikey=${process.env.API_KEY_TWELVEDATA}`);
const payload = {
"action": "subscribe",
"params": {
"symbols": "AAPL,INFY,TRP,QQQ,IXIC,EUR/USD,USD/JPY,BTC/USD,ETH/BTC"
},
}
ws.on('connection',function (steam) {
ws.on('open', (data) => {
console.log("data ==>",data);
ws.emit('subscribe',payload)
})
ws.on('subscribe', (data) => {
console.log("data ==>",data);
})
})
const port = process.env.PORT || 5000;
app.listen(port, () => {
console.log(`I am listening at ${port}`);
});
I created a websocket with my websocket connection on an express application but I am unable to receive any information from the twelvedata server regarding the subscribe event that I have emitted !
This is how the websocket should work as shown by the twelvedata website (look into the screen shots)
I am unable to connect and emit the subscribe event given by the twelvedata's documentation
You don't want to emit events from the websocket (that's for events you want to handle locally), but send, i.e., replace
ws.emit('subscribe',payload)
with
ws.send(payload)
// sending the parameters
ws.on('open', function open() {
ws.send(JSON.stringify(payload));
});
ws.on('message', function message(data) {
// receiving data
console.log('data ===>: ', JSON.parse(data));
});
ws.send did the charm for me

React client receives two connections using Socket.io

I am developing a simple app with SocketIO and I am encountering this problem. In the server I have the following code:
const httpServer = require('http').createServer();
const socketIO = require('socket.io');
const port = process.env.PORT_WS || 5001;
const io = socketIO(httpServer, { cors: { origin: '*' } });
io.on('connection', (socket) => {
console.log('Connected to socket');
socket.on('join-room', () => {
console.log('joined room')
});
});
httpServer.listen(port, () => {
console.log(`Listening on the port ${port}`);
});
In the client I have the following code:
import { io } from 'socket.io-client';
export default class SocketConnection {
constructor() {
this.initializeSocketConnection();
this.initializeSocketEvents();
}
initializeSocketConnection() {
console.log('I am here');
this.socket = io('ws://localhost:5001');
}
initializeSocketEvents() {
this.socket.on('connect', () => {
console.log('Socket connected');
});
}
}
I get in the console two Socket connected messages.
This is not a re-render issue because the I am here message is logged only once.
I am using socket.io version 4.0.1 both in the client and in the backend.
So this is happening because, in React Strict Mode, constructors are called two times. React seems to hide this. As the console.log('Socket connected'); is inside an "on" event, React has no way to "hide" this. Thus, 'I am here' is going to be shown once but 'Socket connected' is going to be shown twice.

Socket.io Client: Always invalid namespace message

Server code:
import http from 'http';
import Koa from 'koa';
import { Server } from 'socket.io';
(async () => {
const app = new Koa();
var server = http.createServer(app.callback());
var io = new Server(server, {
path: '/seacher',
transports: ['websocket'],
});
io.on('connection', (socket) => {
setTimeout(() => socket.emit('message', { say: 'hello' }), 1000);
socket.on('message', (msg) => {
console.log('[msg]', msg);
});
});
server.listen(3000)
})();
Client code:
var socket = io('http://localhost:3000/seacher', {
path: '/seacher',
autoConnect: false,
transports: ['websocket'],
});
socket.on('error', (err) => console.log('error', err));
socket.on('connect', () => console.log('connect'));
socket.connect();
No any messages in browser / nodejs console.
In the Network tab in browser a lot of connections with messages like
Change the client code to this:
var socket = io('http://localhost:3000', { // note changed URL here
path: '/seacher',
autoConnect: false,
transports: ['websocket'],
});
The path option specifies what URL socket.io is going to use internally. You put that in the path option as you have already done in both client and server.
If you put something in the URL you specify like you had 'http://localhost:3000/seacher', then that is the namespace /seacher that you are trying to connect, but your server does not support that namespace.
This is a confusing part of socket.io's design, but path and namespace are not the same thing in socket.io. Do not confuse or mix them.
FYI, there is rarely a reason to customize the path option the way you have done unless you are trying to run more than one socket.io server shared on the same http server (something it does not appear you are doing). By default, the path is /socket.io which makes a lot of sense in logs and debuggers and when accessing the client-side library. I would suggest you remove the path option from both client and server and let it default to /socket.io. And, don't use a path in your connection URL either as that specifies a namespace, not a path.

Socket.io - Emitted event on connect not received in client

I'm using ngx-socket-io on the client in my Angular app. I've followed the setup in the "How to use" section.
I'm trying to emit an event to all connected clients when one client connects using this code:
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
io.on('connect', socket => {
io.emit('foo', 'foo-event');
});
However the clients never receives this event when doing:
constructor(
private socket: Socket
) {
this.socket.fromEvent('foo')
.subscribe((e) => {
console.log(e);
});
}
However if I change the server code to:
io.on('connect', socket => {
socket.on('foo', () => {
io.emit('foo', 'foo-event');
});
});
And the client code to:
constructor(
private socket: Socket
) {
this.socket.emit('foo');
this.socket.fromEvent('foo')
.subscribe((e) => {
console.log(e);
});
}
Then it works as expected.
Why can't I just emit an event and receive it on the client without emitting an event from the client first like in the second example?
According to this answer, I think you should use connection event instead because connect emits just before a successful connection. Thus you can't emit new event.

Debugging socket.io using Smart Websocket Client

I want to manual test my websocket funcstionality.I am using socket.io and just installed a chrome to extension which allows me to connect to my server and send messages to it.
After some research I found out the sceheme that socket.io uses to send messages - 42["{event}", {data}]
I must be doing something wrong because when I try to send this message I dont trigger my callback.
Here is my server side code:
import * as express from 'express';
import * as http from 'http';
import * as socketIo from 'socket.io';
import config from './config';
const app = express();
const server = http.createServer(app);
const io = socketIo(server);
// URL: ws://localhost:1337/socket.io/?EIO=3&transport=websocket
io.on('connection', function(client: socketIo.Client){
console.log('Client connected..');
io.on('auth', (data:any) => {
console.log(data);
});
});
//start our server
server.listen(config.port, () => {
console.log(`Server listening on port ${config.port}.`);
});
And here is the message which I am sending to my server.
42["auth","test"]
Here is a screenshot aswell.
I get the message when I connect to the websocket, but I cant trigger my callback for the 'auth' command.
I had the code wrong..
io.on('connection', function(socket:SocketIO.Socket){
console.log('Client connected..');
socket.on('auth', (data:any) => {
console.log(data);
});
});

Resources