How to Connect WSO2CEP with Socket.io? - node.js

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.

Related

NodeJS "The data will be lost if there is no listener when a Socket emits a 'data' event."

I am making a server in NodeJS using the Net module. It looks like the following:
const net = require('net');
server = new net.Server();
server.listen("{port: 80}");
server.on('connection', socket =>{
socket.on("data", ()=>socket.write("Hey there!"));
});
The issue is that when I get two really close requests for the same client only the first gets served with a "Hey there!" response.
What I have read from the Net docs (https://nodejs.org/api/net.html#net_event_data) is that "If there is no listener when a Socket emits a 'data' event the data will be lost".
Am I loosing the second request because I am still writing the response to the first at ()=>socket.write("Hey there!") when its event arrives?
If that's the case how do I avoid loosing 'data' events when I am serving others?

Forward redis pubsub message to specific socket.io client in express

In my express server, I am using socket.io and Redis pubsub.
The server subscribes a Redis message channel, and forwards Redis message to a specific websocket client when someone publishes new message via Redis.
From what i read from socket.io and Redis documentation, I can send message to a specific client by using the varible socket and call socket.broadcast.to(mySocketID).emit.
But in the following code, what should I do if I wanna emit message to mySocketID inside the redis subscriber, which is out of the scope of io.on('connection')?
var redis = require('redis');
var server = require('http').createServer(app);
var io = require("socket.io")(server);
io.on('connection', function (socket) {
socket.on('whatever_event', function() {
socket.broadcast.to(mySocketID).emit('TEST', 'hello ' + mySocketID);
}
}
var subscriber = redis.createClient();
subscriber.on('message', function (channel, redisMessage) {
// I want to send redisMessage to the websocket client
// Can I access to "socket" in io.on('connection' ...) ?
});
I did something similar with WebSockets a while back (If I understand what you're trying to do). Effectively, I had to create a in-process event proxy layer between the Redis Pub/Sub (plain ol' EventEmitter) and the websocket. Without this layer you're going to have a lot of unneeded connection overhead, by using it you can limit the number of open connections to Redis.
So, the subscriber.on section sends a EventEmitter event (yourEventsObject.emit(/*...*/)). Then inside your socket.io connection callback you respond to these events with listeners (yourEventsObject.on(/*...*/)). When your socket.io connection closes, you need to make sure and clean up these EventEmitter listeners so you don't get errors with closed sockets.
Here is the full file on full source on and the article describing the problem/solution with websockets.

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).

Socket.io emit looping

I would like to be consistent with my socket.io "hooks". I use this format below pretty consistently, and it does not appear to fall into an infinite loop.
// inside my nodejs app
socket.on('foo', function (data) {
socket.emit('foo');
});
It only runs once when the hook is triggered from the client side, so it appears to be safe. But why would it not go in an infinite loop in the server side ? is this by accident or design ?
This behavior is by design, not a coincidence or accident
client: emit a message to server with a method
server: receive message from client with an event handler
server: send a message to client with a method
client: receive a message from server with an event handler
server socket receive a message from client
client.socket.emit('foo',aMessage) on foo event
socket.on('foo', function (data) {
//then server emit a message to connected clients
//not to server this is why not go through an infinite loop
socket.emit('foo');
});
then 'client' receive the message from server
chat.socket.on('foo', function(data){
console.log('got new message from server...',data)
})

Verify that the client has received the message from the server

In a chat service that I'm building, I need to send messages directly from the server.
I have found no solution, there is an example in the documentation:
// SERVER
io.sockets.on('connection', function (socket) {
socket.on('ferret', function (name, fn) {
fn('woot');
});
});
// CLIENT
socket.on('connect', function () { // TIP: you can avoid listening on `connect` and listen on events directly too!
socket.emit('ferret', 'tobi', function (data) {
console.log(data); // data will be 'woot'
});
});
but does the opposite of what I need!
I need to do the emit from the server and receive a confirmation of receipt from the client!
Is there a way to do this?
there is no guarantee as the connection can be killed before the servers message reaches the client. thus there is also no event on the server like "clientGotMessage". if a message MUST reach the user there is no other way than to tell the server that you received the message on the client.
You can do this 'easy' by sending a number down. client and server keep track of that number. each time the server sends, it counts up, each time the client receives, it counts up. When the client sends something, it sends the number, so the server will see if the client has everything. If the client missed a message, the next message will have a number that the client wont accept and request the lost message from the server.

Resources