We are using Tokbox to implement a set of pre-defined chat rooms.
Each room has a moderator and a specific group of users who can join the chat room only when the moderator has activated the chat room.
This has gone very well and quite smoothly.
My question is: How could we set up say a "super user" so that they may terminate any active chat session that might be going on? This superuser is not necessarily an active participant in any room. But, we would like to set up some sort of admin page where there is a button for each room that says "emergency terminate" or something like that.
We have database roles and user setup. We are just trying to figure out the best approach to do this with the Tokbox API.
TokBox Developer Evangelist here.
A client connected to a session with a moderator token can disconnect other connected clients in that session.
There is no concept of "super user", but you can use the use the OpenTok REST API to force disconnect connected clients from any session. You can also use the OpenTok PHP SDK to accomplish this.
use OpenTok\OpenTok;
$opentok = new OpenTok($apiKey, $apiSecret);
$sessionId = ""; // the session the client is connected to
$connectionId = ""; // this connection Id of client you want to force disconnect
$opentok->forceDisconnect($sessionId, $connectionId);
As you can see, you would need to know the connectionId of the client that you want to disconnect. The connectionId is part of the Connection Event that is dispatched with connectionCreated and connectionDestroyed events on the client side. You can also use Session Monitoring to receive these connection events via a webhook on your server.
Related
I'm trying to implement a communication method between client and admin (bidirectional) using Paho MQTT JS + Mosquitto broker 1.6.8 and I'm having some trouble with retained messages and persistent sessions.
What I want to accomplish:
My web client is subscribed to a topic where the admin publishes (let's say topicA) and the admin is subscribed to a topic where the client publishes (topicB). When any of the users received a message for that topic, it appears on the screen, and they keep appearing below the previous so that they form a list of messages. When they are both online, they have to see the messages that are being sent and if they go offline, they have to see the old and new messages as well. Also, the users must have the ability to clear the list of messages.
What I've tried so far:
My first try was setting the published messages with the retained value to true, so that the message can be delivered to future subscribers. However, I see that only the last message is retained. I investigated and found that I can establish a persistent session (by cleanSession: false) between broker and client, so that if I set the qos of the message to a value greater than 0 (0 or 1) and the client is subscribed to the topic, they'll get all the undelivered messages. This doesn't work for me, or at least the way I expect it to work. I've tried removing the Mosquitto Db and restarting (didn't change anything). I also tried using the same id for all clients and another id for all admins, because I thought that maybe, the broker saves the messages only for a particular clientID, so if a client with a completely different ID connects, they won't get the messages.
Is there a way of delivering ALL the undelivered messages (because of one client being online and the admin offline, or viceversa) and not only the las one (retained)? Or is there a way of retaining more than one message (better in my opinion, if I could clear the retained ones by sending a null payload) ?
First every client must have a unique client id. When there is a client id clash the oldest connected client will be disconnected.
Second it's the QoS of the subscription, not the publish that dictates if the broker will queue a message for a offline client with a persistent session
So for a client to receive messages published while it is offline, it must
Have previously connected and subscribed to the topic with a QoS of 1 or 2
When reconnecting it must use the same client id as last time
Have cleansession set to false
The messages will only be delivered once so there is no need to clear the messages, but if you don't have to receive the queued messages, set the cleansession flash to true.
The broker will only retain the last message published on a given topic that had the retained bit set, there is no way to change this.
My end goal here is to subscribe web clients to topics in Firebase Cloud Messaging to receive simple data push events, partitioned by keys. Via this question, that seems to be possible, but only if you can send the clients' registration keys to an app server you control using the FCM Admin API: How to subscribe to topics with web browser using Firebase Cloud Messaging
Also, via https://firebase.google.com/docs/cloud-messaging/js/client, it seems to be required to request permission from the user to show desktop notifications in order to get access to the registration token for Firebase messaging.
Is there any way to tell Firebase no, I absolutely do not want desktop notifications, in fact please never show them, I just want to use data messages and never notification? And then, to get the registration token? Alternatively, is there some other way to subscribe to topics from a web client?
There is currently no other alternative to get a registration token nor is there a different way to subscribe to topics for a web client.
You already know this, but might as well mention it. Requesting permissions is a must for security purposes (preventing notifications not wanted by the user) and that in order to subscribe a web client to a topic, you'll first have to get a token (which won't generate unless the user grants permission).
Looks like you are looking for Pusher
User channel for communication. Works with out token and support bidirectional contact.
Sample code
Back End
pusher->trigger('my-channel', 'my-event', [
'message' => 'hello world'
]);
Front End
var channel = pusher.subscribe('my-channel');
channel.bind('my-event', function(data) {
alert('Received my-event with message: ' + data.message);
});
Im making a simple chat app that sends messages through a redis pub/sub channel. I do not use any login options just lets the user select a username and chat. I am trying to implement private chat where one client is able to communicate to another connect client. I am new to chat client programming, I am trying to figure out how to communicate with only one client. What are some options I could consider to get the ability to chat 1 on 1? I don't mind changing my architecture to incorporate a new tool. Any suggestions is appreciated
I did something similar with raw sockets. I held user objects which contained the connected socket, the name, and whether they are chatting. If a user is not in chat he can type a command /list users which gives the list of users currently connected. When he has found someone to chat with he enters the command /chat bob. If the user bob is already chatting he will receive a message from the server saying that bob is in a chat already. Otherwise a chat session will be established between the two users. They now will be in chat until one of them enters /endchat. Then they will be able to find new people to chat with.
The trick is implementing the server so it can track a list of users and their chatting status and who they are in chat with so when ever they type /endchat the other user can be notified.
The combination of Nodejs + Socket.io would solve your problem i suppose. Specifically rooms functionality is what you are looking for here.
Lets say you have two users bob and gob. Considering both are online (although you can add Redis as a session store and for storing history later, which i did in my case). Say bob wants to chat with gob he selects gob. Now make bob join a room using
var roomname = 'bob'>'gob'?'bob'+'gob':'gob'+'bob' ;
//this type of naming ensures roomname is same for both users
socket.join(roomname);
This will work only if both have chosen each other. So now when gob selects bob both are joined in the same room. Whenever someone sends a message make them emit to that room using
socket.broadcast.to(roomname).emit('message_event',msgObj);
Make sure you have have added the listener
socket.on('message_event',messageHandler);
When chat is finished make them leave the room using
socket.leave(roomname);
Let's say I'm making a chat, is it possible to sent messages to specific users and particularly groups of users? Can I hook up ID's to clients that have been logged on and groups that have been started, so I can sent messages to the server using these ID's and the server just sends these messages to the correct people? The chat app would look much like a chat from an MMO game where you can receive broadcast (from entire network), room, private, group and party messages in the same window.
Also I have a database behind this, is it possible I can use this for the above? Like using the same user ID's as in the database? Likewise I'm storing groups with an ID.
You can create rooms or even private chats using web sockets, there are lots of examples out there. I have only used Socket.IO and they are finally 1.0 production ready. Check their docs: http://socket.io/docs/rooms-and-namespaces/
// Join
io.on('connection', function(socket){
socket.join('some room');
});
// Emit
io.to('some room').emit('some event'):
I am trying build a chat server using MEAN Stack (not using redis), which uses socket.io for enabling real time chat. For private messaging, I want to implement the built-in "room" feature of socket.io. The flow goes as follows :
User1 wants to start a conversation with User2, so User1 emits an event, which the server catches.
In the server, I store this conversation in database and join User1 to a room. If User2 is online, then I join User2 also to this room. For achieving this step, I need access to the socket of User2.
After a good amount of research, I found this method to store the "socket" of every connected user in an array(or dictionary).
I was wondering if there is any other method to retrieve the socket other than storing it in an array.
No, no better way, except if you use different namespace for the two users, but i don't think it's your case.
I implemented a basic POC (proof of concept) a couple years ago using faye.
In my case I created a unique channel for active users. The channel name was the same as the unique user identifier from mongo ( _id ). This allowed me to send messages to the correct user without having to store information about their connection.
Please note that I did not do any performance testing and that you would need to have a lot of connections open.
I did a similar implementation using faye by broadcasting to channels, in that case I did store in the database who was connected to a specific channel.