How to listen session:success event in nexmo client js? - vonage

I follow tutorial here: https://developer.nexmo.com/client-sdk/tutorials/app-to-phone/client-sdk/app-to-phone/main-screen/javascript
listen session:success event with bellow script not working.
const status = $('.input');
app.on('session:success', () => {
status.val('Ready to call.');
});
Is there any other event i can listen?

It seems i don't need to listen nexmo app event.
Just check it with if condition.
if (app.session.sessionReady) {
callStatus.val("Ready for call.");
}

Related

Socket.Io not emitting immediately after first emit (order important)

Environment:
Backend
node:latest
socket.io | 4.5.2
Frontend
React Native | 0.70.4
socket.io-client | 4.6.0
both Android and iOS
Here is my NodeJs entry file:
const numCPUs = cpus().length
if (cluster.isPrimary) {
const app = express()
const httpServer = http.createServer(app)
setupMaster(httpServer, { loadBalancingMethod: 'least-connection' })
setupPrimary()
for (let i = 0; i < numCPUs; i++) {
cluster.fork()
}
cluster.on('exit', (worker) => {
cluster.fork()
})
} else {
const app = express()
const httpServer = http.createServer(app)
const io = new Server(httpServer, { maxHttpBufferSize: 1e8 })
io.adapter(createAdapter())
setupWorker(io)
API.Socket.init(io, process.pid)
middlewares.forEach((middleware: any) => app.use(middleware))
routes.forEach((route) => app.use(route.path, route.handler))
httpServer.listen(CONFIG.PORT, () => {})
}
I have a simple chat application.
When user A sends message to user B, new chat message and notification is recorded in database. Now that chat message and notification* should be sent to the B user. There are 2 socket emit-functions for that:
sendNewNotification(
notification: BE.Entities.TNotification,
toUser: string,
) {
this.io
?.to(toUser)
.volatile.emit(ECustomEvents.NewNotification, notification)
}
sendPrivateMessage(
toUser: string | Array<string>,
chatMessage: BE.Entities.TChatMessage,
sourceUser: BE.Entities.TUser,
) {
this.io
?.to(toUser)
.volatile.emit(ECustomEvents.PrivateMessage, chatMessage, sourceUser)
}
If I do it like this, the targetUser is not going to receive the event with the newChatMessage however he will receive the savedNotification
API.Socket.sendPrivateMessage(targetUserId, newChatMessage, userToPass)
API.Socket.sendNewNotification(savedNotification, targetUserId)
Now, if I switch these lines:
API.Socket.sendNewNotification(savedNotification, targetUserId)
API.Socket.sendPrivateMessage(targetUserId, newChatMessage, userToPass)
the behavior would be as expected: the target user B will receive both saved notification and new chat message
How is that possible? What could be wrong?
Thank you mates in advance!
With the current information, I'm not so sure the order matters but perhaps that it's a side-effect / coincidence. Are you checking anywhere to make sure the server-side socket is ready before the client emits?
Consider this super simple WebSocket chat sandbox:
One of the issues I noticed when writing this is when the server WebSocket is not ready, I could not emit from the client to the server. To make sure the server is ready, I sent a ping from the server to the client notifying the client that the server is ready:
wss.on("connection", async function connection(client, request) {
console.log("user connected", Date.now());
client.send(JSON.stringify({ ready: true }));
...
});
I also notice you are usingg the volatile.emit which according to the documentation:
Volatile events
Volatile events are events that will not be sent if the underlying connection is not ready (a bit like UDP, in terms of reliability).
This can be interesting for example if you need to send the position of the characters in an online game (as only the latest values are useful).
socket.volatile.emit("hello", "might or might not be received");
The Socket.IO docs have a similar listener which lets you know when the server is ready.
If you prevent the client from emitting until the server is ready, you can avoid this issue. You also should not need to use the volatile.emit for something that must be delivered.

How to make Sails.js app listen to events of ethereum blokchain to perform CRUD on persistence layer

I have a smart contract deployed on Ethereum blockchain and it emits some event with necessary data.
I have a sails.js application which needs to listen to this event.
Roughly, the javascript code looks like -
var event = contract.myEvent();
event.watch((err, res) => {
console.log(res); // event response
// API call to DB for persistence
});
My question is where should this code sit in sails.js application as sails.js follows MVC, is it a good idea to use sails.js ?
Suggestions about design pattern are appreciated.
This code should be excuted as a Service at the application start time.
for example you can create a file named EventsService.js :
let event = contract.myEvent();
exports.start = function () {
event.watch((err, res) => {
console.log(res); // event response
// API call to DB for persistence
});
}
and then you can start the service like this: (from the app.js file)
const eventService = require('path/to/EventService.js');
eventService.start();

how to detect socket.io event which is not registered?

I'm using node.js and socket.io for a chat program and I listen to some events. Here is the relevant code:
server: io.sockets.on('connection',( socket ) => {
socket.on('joinRoom',( data )=>{ do with message });
socket.on('leaveRoom',( data )=>{ do with message });
}
client: io.emit('joinRoom',{uid:11});
If the client emits an event which is not registered as io.emit('noEvent',{});, how does the server detect it?
Use socketio-wildcard plugin.
You can use the wildcard plugin for socket IO to do that as suggested in SocketIO official documentation here, like so:
socket.on('*', function(packet){
// client.emit('foo', 'bar', 'baz')
packet.data === ['foo', 'bar', 'baz']
});
Because the socket server is listening for something to happen on the port not the 'event'. So if something is 'emitted' and there is a 'listener' it will pick that up, it just won't know exactly what to do with it.
Not sure if this will help but here is the socket.io cheetsheet
In 3.x, it can be done without any plugins using onAny listener:
socket.onAny((eventName, ...args) => {
const isNotRegistered = !Object.keys(socket._events).includes(eventName)
if (isNotRegistered) {
// Event is not registered
}
})

ZeroMQ: Can subscribers publish?

I am trying to implement an idea I have for a pub/sub app I'm doing in Node.js with 0mq. I want to use the publishing of messages as a kind of event system.
Here's an example: Say I have a publisher and two subscribers.
The publisher sends a message whenever a file is changed:
//publisher.js
'use strict';
const fs = require('fs'),
zmq = require('zmq'),
// create publisher endpoint
publisher = zmq.socket('pub'),
filename = 'target.txt';
fs.watch(filename, function(){
// send message to any subscribers
publisher.send('files changed');
});
// listen on TCP port 5432
publisher.bind('tcp://*:5432', function(err) {
console.log('Listening for zmq subscribers...');
});
Subscriber #1 logs everything that happens to the console:
//subscriber1.js
'use strict';
const zmq = require('zmq'),
subscriber = zmq.socket('sub');
// subscribe to all messages
subscriber.subscribe('');
// handle messages from publisher
subscriber.on("message", function(data) {
console.log('Got a message: ' + data);
});
// connect to publisher
subscriber.connect("tcp://localhost:5432");
Subscriber #2 validates the changes to the file and sends a message to let us know that it looks ok:
//subscriber2.js
'use strict';
const zmq = require('zmq'),
subscriber = zmq.socket('sub');
// subscribe to all messages
subscriber.subscribe('');
// handle messages from publisher
subscriber.on("message", function(data) {
//pretend I did some work here
subscriber.send('File looks great!');
});
// connect to publisher
subscriber.connect("tcp://localhost:5432");
What I'd expect is that sending a message back through the socket from subscriber 2 would forward it on to subscriber 1, who would log it. But that doesn't seem to be happening.
I am probably fundamentally misunderstanding pub/sub, but is it possible to do what I'm talking about? If so, do I need to use a different pattern, or am I just using the zmq API wrong?
I had to do a little extra plumbing to get the results I was looking for.
Had to add a publisher socket to subscriber-publisher.js, and publish from it to a different port. Then I had to subscribe subscriber.js to the two ports published by publisher.js and subscriber-publisher.js.
So now I understand that in order to do this with pub-sub, I have to build more sockets, and must do a bit more manual subscription the I thought.

How can I send packets between the browser and server with socket.io, but only when there is more than one client?

In my normal setup, the client will emit data to my server regardless of whether or not there is another client to receive it. How can I make it so that it only sends packets when the user-count is > 1? I'm using node with socket.io.
To do this you would want to listen to the connection event on your server (as well as disconnect) and maintain a list of clients which are connected in a 'global' variable. When more than 1 client is connected send out a message to all connected clients to know they can start sending messages, like so:
var app = require('express').createServer(),
io = require('socket.io').listen(app);
app.listen(80);
//setup express
var clients = [];
io.sockets.on('connection', function (socket) {
clients.push(socket);
if (clients.length > 1) {
io.socket.emit('start talking');
}
socket.on('disconnect', function () {
var index = clients.indexOf(socket);
clients = clients.slice(0, index).concat(clients.slice(index + 1));
if (clients.length <= 1) {
io.sockets.emit('quiet time');
};
});
});
Note: I'm making an assumption here that the socket is passed to the disconnect event, I'm pretty sure it is but haven't had a chance to test.
The disconnect event wont receive the socket passed into it but because the event handler is registered within the closure scope of the initial connection you will have access to it.

Resources