I have a use case where I need to take input from browser pass it to my node server over a socket, this input is then send to a third party website for processing again over socket. The result received from the third party website needs to be sent back to browser.
node server
var express = require('express');
var app = express();
var server = require('http').createServer(app);
var socketIO = require('socket.io'),
server, io;
var thirdPartSocketClient = require('socket.io-client');
//Custom imports
var thirdParty = require('./ms_socket.js');
var socket = socketIO(server);
socket.on('connection', function(client) {
var token = null;
//Token from third party site that we should have before sending the actual info
thirdParty.getToken(function callback(returnToken) {
token = returnToken;
});
thirdPartSocketClient = thirdParty.getTranslation(token);
client.on('audio', function(data) {
thirdPartSocketClient.emit(data);
});
});
server.listen(8080, function() {
console.log('Open http://localhost:8080 in your browser');
});
ms_socket.js
//Exported function making a socket call to third party service
var exports = module.exports = {};
var request = require('request');
var wsClient = require('socket.io-client');
var fs = require('fs');
exports.getToken = function(callback) {
//send back the token
}
exports.getTranslation = function(accessToken) {
var ws = new wsClient(thirdPartySocketURL);
// event for connection failure
ws.on('connectFailed', function(error) {
console.log('Initial connection failed: ' + error.toString());
});
// event for connection succeed
ws.on('connect', function(connection) {
console.log('Websocket client connected');
// process message that is returned
//processMessage would process the incoming msg from third party service
connection.on('message', processMessage);
connection.on('close', function(reasonCode, description) {
console.log('Connection closed: ' + reasonCode);
});
// print out the error
connection.on('error', function(error) {
console.log('Connection error: ' + error.toString());
});
});
// connect to the service
ws.connect(thirdPartySocketURL, null, null, {
'Authorization': 'Bearer ' + accessToken
});
return ws;
}; //End of export function
I am able to receive the data from browser, make a connection to third party service (can see the socket connection) and emit the data. however I am unable to receive the reply back from the third part service.
Is it because node is not listening to my socket events of thirdparty ?
Not sure exactly why its not working.
I save the data locally on the server, read the file and then send it, then I get a response back from the service.
If this is not a "right" design can you please suggest a good way, should I be using message queues (if yes, feel free to recommend one)
Thanks
Related
I have a Node/Vue application. I am consuming a WebSocket from Binance, a crypto exchange. I can see the quotes on the server console as I log them, I can send them to the browser for a short period of time before the client stops logging them.
Browser just using WebSocket API
Node using ws library
Node code, this I am running as it's own service as its just this.
'use strict';
const WebSocket = require('ws');
const binanceWS = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt#trade')
const server = new WebSocket.Server({ port: 5002 });
//websocket connection event will return a socket you can later use
binanceWS.on("open", function() {
console.log("connected to Binance");
});
binanceWS.on('message', function(data){
console.log(data);
server.on('connection', function connection(ws){
console.log("Connected a new client");
ws.send(data);
});
server.on('closed', function (id){
console.log("connection closed");
console.log(id);
});
server.on('error', function (err){
console.log(err)
})
})
On the Client side I am using Vue and in the app.js file I have this on the created hook.
let socket = new WebSocket("ws://localhost:5002")
socket.addEventListener('message', function(event){
let quotes = JSON.parse(event.data);
console.log(quotes.p)
});
socket.addEventListener('error', function(event){
console.log("closing because " + event);
})
Right now I am only listening to the consoles in the above app.vue file.
What I see in the browser console is a lot of quotes, then they stop after a second or 2. There can be over a thousand quotes in some times. Then on occasion I see a console.log('created') that I have in a child component of app.vue. In many cases this is the last thing in the console after hundreds of quotes.
In the console.log for the server I see a lot of sessions being created with one page refresh. So much that it fills my console.
So I'm not sure I am creating the connections correcly, I am not sure if Vue is somehow stopping the console.log's?
I don't see any errors anywhere and the entire time in my server console the Binance API continues streaming.
you have to write server event listener outside binance on message handler;
then you can pass messages from binance to the server by emitting new event to the server
on receiving message from binance you can send data to all connection on the server
Or Try this code I think it will work :
'use strict';
const WebSocket = require('ws');
const binanceWS = new WebSocket('wss://stream.binance.com:9443/ws/btcusdt#trade')
const server = new WebSocket.Server({ port: 5002 });
server.on('connection', function connection(ws){
console.log("Connected a new client");
});
server.on('closed', function (id){
console.log("connection closed");
console.log(id);
});
server.on('error', function (err){
console.log(err)
})
//websocket connection event will return a socket you can later use
binanceWS.on("open", function() {
console.log("connected to Binance");
});
binanceWS.on('message', function(data){
console.log(data);
server.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
})
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.
I am using a TCP connection via node.js to connect to a certain port in windows, however I want the connection to be established until the user logs out .
In other words I want to add the TCP Connection as a session attribute in node.js ,so that it will last as long as the session is alive for the user.
I have tried this ,but it doesn't work.
Code :
var express = require('express');
var authRouter = express.Router();
var createTCPConnection = function () {
var net = require('net');
var HOST = '127.0.0.1';
var PORT = 6969;
var client = new net.Socket();
client.connect(PORT, HOST, function() {
console.log('CONNECTED TO: ' + HOST + ':' + PORT);
// Write a message to the socket as soon as the client is connected, the server will receive it as message from the client
client.write('I am Chuck1 Norris!');
});
// Add a 'data' event handler for the client socket
// data is what the server sent to this socket
client.on('data', function(data) {
// Close the client socket completely
//client.destroy();
});
// Add a 'close' event handler for the client socket
client.on('close', function() {
console.log('Connection closed');
});
return client;
};
authRouter.route('/').get(function(req, res) {
var sess = req.session;
if (sess.username) {
//If Session has username attribute, it is a valid session
res.render('dashboard', {
title : 'Welcome To Operator Screen',
username : sess.username
});
if(sess.tcpClient === undefined) {
console.log('Establishing TcpClient');
sess.tcpClient = createTCPConnection();
} else {
console.log('TcpClient already established');
}
} else {
//Invalid/expired session, redirect to homepage
res.redirect('/logout');
}
});
module.exports = authRouter;
I'm new to socket.io, and I'm doing a simple API with NodeJS (express 4). I'm developing an action that is similar to the old "poke" action at facebook. A user send a poke to other user, and this one gets a notification on real time (this is the reason why I am using socket.io).
This is the code:
app.js
var port = 3000;
var app = module.exports = express();
var server = require('http').Server(app);
...
server.listen(port);
require('./config/socket-io')(app, server, secret);
socket-io.js
module.exports = function(app, server, secret) {
var clients = {};
console.log("initiating sockets...");
var sio = require('socket.io').listen(server, {'log level': 2});
sio.on('connection', function (socket) {
console.log("...new connection: "+socket.client.id);
clients[socket.id] = socket;
socket.emit('identification', { data : socket.client.id });
socket.on('newShoutOut', function(data) {
var receptor = data.idTo;
var emiter = socket.client.id;
console.log("...new shout out from " +emiter+ " to "+receptor);
sio.sockets.sockets[receptor].emit({ data : data.data, from : emiter });
});
socket.on('disconnect', function() {
console.log("..."+socket.client.id + " disconnected");
});
});
};
Here you can differentiate three states:
Connection: The server detects all the clients connection to the host:port. After that, the server sends to each client his ID. This works fine.
Send message: One client sends a notification to other client. For now, the server receives the notification from one client, but the "receiver" doesn't receive anything.
Disconnection: Doesn't matter in this case.
My question is, what is the way to send a message to a client directly knowing the ID? What I am doing wrong? I tried so many options to send a message directly to a specific client ID but didn't work...
EDIT
Frontend
var socket = io('http://localhost:3000');
var id = "";
socket.on('connection', function (data) {
console.log("connected!");
console.log(data);
});
socket.on('identification', function(data) {
id = data.data;
$("#socket_info h1").html("ID: "+id);
});
socket.on('newShoutOut', function(data) {
console.log("newShoutOut received!");
});
Ok, so I assume the shoutout is coming from a user? You will need to create the event on the clientside, such as:
var button = $('#button');
button.on('click', function() {
var msg = 'message',
userID = '123'; //get the ID who they are messaging
socket.emit('sendShoutOut', {msg: msg, id: userID});
});
Then you will need to receive that response on the server, and reply to the user in that function:
socket.on('sendShoutOut', function( data ) {
socket.sockets.sockets[data.id].emit('sendPrivateMsg', { data : data.msg, from : emiter });
});
Lastly, the reciever must be notified, so you will need to handle the response on the client:
socket.on('sendPrivateMsg', function( data ) {
alert(data);
});
Hope this helps.
I have a simple client server web app that is using web sockets to send / receive information. The client can connect and receives properly the config file but then when I try to send a "test' message from the client using "socket.emit('message', {my: 'data'});" it doesn't display on the server. I did check with wireshark and the packets are arriving at the server.
var sIoPort = 8181;
var host = '192.168.4.111';
var fs = require('fs');
var iniMsg = fs.readFileSync('data.json','utf8');
var http = require("http").createServer(function (req, res) {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(index);
});
http.listen(sIoPort,host);
var browserServer = require('socket.io').listen(http);
browserServer.on('connection', function (socket) {
console.log('Client websocket connected');
// send the config file if available
browserServer.sockets.emit('msg',iniMsg.toString());
});
browserServer.on('message', function (message) {
console.log('received message: ' + message);
});
client side
///////////////////////////////////////////////////////////////////////////////
socket = io.connect("192.168.4.111",{"port":8181});
socket.on('connect',function() {if(DEBUG) console.log('Socket Connected');});
socket.emit('message', {my: 'data'}); // test if server receives message
socket.on('msg',function(data) {
var json = JSON.parse(data);
// add the maps to the the GUI
switch(json.type) {
case 'maps': add_maps_from_json(json, null);
break;
}
});
socket.on('disconnect',function() {if(DEBUG) console.log('Socket Disconnected');});
/////////////////////////////////////////////////////////////////////////////////
Modify the serverside listener so it's paying attention to events on a socket:
browserServer.on('connection', function (socket) {
console.log('Client websocket connected');
// send the config file if available
browserServer.sockets.emit('msg',iniMsg.toString());
socket.on('message', function (message) {
console.log('received message: ' + message);
});
});