Modifying the websocket sent message on proxy server - node.js

I created a proxy server (node-http-proxy) to redirect websocket connections to another websocket server like:
websocket client <-----> proxy <-----> websocket target server
In order to control the messages that sent from client to the sever, I would like to know what messages are sent to the server and do some filtering. I found the following codes helping me to get the sent messages but I can't filter the unwanted messages (such as 'hello'). Is there other method (or package) I can use to add some logic before the messages are sent to target server ?
proxy.on('proxyReqWs', function(proxyReq, req, socket, res, options) {
var parser = new WsParser(0, false);
socket.pipe(parser);
parser.on('frame', function (frame) {
// handle the frame
console.log('Up:',frame);
console.log('Up data:'+frame.data);
});
});

Related

Socketio : P2P connection with NodeJS and Wordpress

I have did integration for Socket.io and WordPress CF7. Working properly as expected I have an issue with multiple domains.
For eg. I have 15 domains like,
example.com
stage.example.com
stage2.example.com
newdmain.com
mydomain.com
Server running on node.myserver.com
Now, I want to create request from client and response on same client. As I check when I run websocket from server and hit api will broadcast on all connected domain.
app.post('/contact-webhook', function(req, res){
// check if it's a valid request from WooCommerce
if (!req.headers['Secret-Key']) return res.status(401).end()
// parse our data
const payload = req.body
// we could use any event handler here
socketIO.emit("newNotification", payload)
// end response
res.status(200).end()
})
When raise request then server will broadcast on all server.
Refer question : socket.io - send notification to admin when order place in WooCommerce

Using Socket.io with Sequelize

I am trying to use Socket.io and Sequelize to create a chat app. Socket.io will handle the socket to allow for instant messaging. Sequelize will handle storing the messages so when you refresh the screen you still have your messages.
What is happening is that on localhost my socket works, but it does not send the messages to the database. When I put it onto Heroku, my database worked, but it does not use the sockets.
My socket is located in app.js and my database route is located in routes/messages.js.
I have been working on this bug for a while now and I have been trying to get help with it. I think the best way to share this is with my markdown I created detailing my efforts to fix my bug that can be found at here. My repo for this can be found here.
There are a few different parts that you need to distinguish:
the HTTP server, in your code represented by the variable http
the Express app, represented by app
the Socket.IO server, represented by io
a Socket.IO (client) connection (see below)
The HTTP server directs "normal" HTTP requests to the Express app, which will handle them according to the middleware and routes that are set up. A router handler gets called with (at least) two arguments, generally called req and res, to represent the (incoming) HTTP request and the (outgoing) HTTP response.
The Socket.IO server gets to handle specific Socket.IO requests, which get sent to the server by the Socket.IO client (running in the browser). When such a client sets up a connection with the server, the connection event gets triggered on the server. Any handlers for this event will get passed an argument, generally called socket, that represents the (bidirectional) connection with that client.
That Socket.IO connection can receive messages (sent from the client running in the browser), which trigger events on the socket. You can install a handler to listen for particular messages (like "chat message"), which will receive, as argument, the data that was sent to it by the client.
The issue in your code seems to be with setting up everything to handle those chat messages. The correct setup order would be:
listen on the Socket.IO server for connection events
when such an event is received, add a listener for the chat message event on the connection
when such an event is received, write the data to the database.
In code:
// Listen for new client connections.
io.on('connection', function(socket) {
// Listen for the client to send a _"chat message"_ message.
socket.on('chat message', function(data) {
// Store the data in the database.
models.Messages.create({
message : data.message,
username : data.username
});
});
});
As you can see, req and res aren't available inside of those Socket.IO event handlers, because those are only used for normal HTTP requests.
Also, as opposed to HTTP, you don't necessarily have to send anything back to the client when you have received a message, so I left that part out. The handler above only writes the message data to the database (it also doesn't check for, or handle, errors, which eventually you should add).

How to Connect WSO2CEP with Socket.io?

I want to create an Event Publisher that connect via Websocket. When I try to connect it with my simple socket io server, the url is
ws://localhost:3000/socket.io/
It didn't receive the stream..
I've set the inline format for the stream like this :
42["input-message",{"LAT":{{latitude}},"LON":{{longitude}}}]
If I understand your question correctly,
you do not get any errors when the event is published from the CEP
server
but the socket io server does not show any indication that it
received the event either.
CEP server showing no error logs means:
CEP server is successfully connected to the socket io server. (if the connection is dropped, then you should see an error log, and CEP will try to reconnect)
Probably the event was sent to socket io server by Websocket publisher (or the Websocket publisher did not recieve any event at all to be sent to socket io server)
(When you send an event, if the CEP server cannot parse the event, then also you should see an error log.)
Here are some points which might help you to troubleshoot the issue:
Enable tracing in your websocket publisher (You may refer to this 'Event Tracer' doc). Then send an event and check the traces. This will allow you to verify whether the Websocket publisher recieved the event.
If there are traces shown for the publisher, but still no event received at the socket io server, then it could be that some error occurs at socket io server, and the exception is not logged (might have being swallowed).
Hope this will help.
Because I cannot directly connect to the socket.io, thus I created a simple websocket that act as a middleware that sending the input from WSO2CEP into the socket.io
var io = require('socket.io').listen(server);
io.set('origins', '*:*');
var WebSocketServer = require('ws').Server,
wss = new WebSocketServer({ port: 8087 })
//wss sending every message that it received to the socket.io
wss.on('connection', function connection(ws) {
console.log('a WSO2CEP-PUBLISHER is connected');
ws.on('message', function incoming(message) {
console.log('received: %s', message);
io.emit('input-message', JSON.parse(message));
});
});
notice that, the data that come from event publisher is string formatted, so if needed to send it as a JSON object, than use JSON.parse() function.

How to detect the socket server authorization failure on client side in socket.io?

I want to connect an js socket client to socket.io server using
socket = io.connect(). But on server side i m using io.use() method to check whether this socket connection contains cookies or not. I restrict the request on socket server to make connection if socket initial handshake does not contain cookies. by passing
next(new Error("Authentication Error")). But i m not able to catch this error on client side. I want to notify the client of invalid login session and login again.
Thanks
Thanks Andrey... I got success with
socket.on("error", function()
{
//function to perform on occurance of authorisation failure
})
I think you need to listen on connect_error:
socket.on('connection_error', function(data) {
// data here should be an Error object sent by server
});
The documentation is awful, but here is a little hint (found here):
Errors passed to middleware callbacks are sent as special error
packets to clients.

Generating socket.io at Server side as Rest request

There is a way to manage the socket.io creation at Server Side?, Currently, I couldn't found any doc, Only found in relation with the socket is created per request from a client "io.connect(server)".
The current flow work OK:
Set Socket.io (at Node.js) at SERVER:PORT
Client connect to SERVER
using io.connect(SERVER:PORT)
I wonder if it is possible ? Trying to do:
Set Socket.io (at Node.js) at SERVER:PORT
Recieved a POST (REST) - Server side
Create/Open Socket.io a server side.
At response of Post send the id?
the clien open a socke.io
Sent to client socket.id to client as
So Far, looking in deep on the code and doc, I found that socket.io support namespaces, so I used this in order to manage client connection id.
at server.js
var app = express();
var server = require('http').createServer(app),
io = require('socket.io').listen(server,{ log: false });
// Rest New Process
function generateNameSpaceWs (responce, request) {
io.of("/" + id).on('connection', handler);
response.send(id);
}
app.post("/newWS", function (res, req) {
return generateNameSpaceWs(res, req);
}
at Client.js
function makeWS(){
var ws, c = new XMLHttpRequest();
c.open("GET", url, false);
c.send();
if (c.status == 200){
id = JSON.parse(c.responseText);
ws = new io.connect("server/" + id)
}
So far you are doing right, if I understand your question correctly, you are trying to authenticate connection via POST, so that user can only connect to server via socket if server responds to ID. This is a roundabout way. Use the socket instead of POST.
Socket server has to be running already, and accepts connection via io.sockets.on('connection'), at server you can choose whether to accept it or reject it ,do socket.disconnect('unauthorized') to close connection from server.
I would you suggest you do this :
Set Socket.io (at Node.js) at SERVER:PORT
Client connect to SERVER using io.connect(SERVER:PORT)
Send what you are sending in POST over socket.
Authenticate/Process on io.sockets.on('connection', function(socket) at server.
Close socket if unathorized.
Send back ID data to client.
This doesn't seem possible -- while the official documentation for socket.io is lacking, the documentation for the net module indicates that the only way to create a socket is to initiate it server side.
However, you can still achieve the desired effect by creating an id for the socket on the server to associate with the socket. That is,
Set Socket.io (at Node.js) at SERVER:PORT
Recieved POST (REST) - Server side
Create id (Note:This could be done before step 2)
At response of Post send the id!
Client connect to SERVER
using io.connect(SERVER:PORT)
The client sends the id to the server using something like
socket.emit("set_id",id)
The server recieves the id and associates it with the socket using something like
socket.on("set_id",function(id){
socket.set("id",id)
}
Now you can reference the socket using the id that you created!
Good luck!

Resources