How can I handle disconnect event using graphql-subscriptions - websocket

I am using graphql-subscriptions to manage session (rooms).
I have simple application like "chat".
I can send message to chat using:
import { PubSub } from 'graphql-subscriptions';
...
pubSub.publish(triggerName, payload)
I can listen to subscription events..
But I don't know how to properly handle when user left to room (for example closing full browser)...
Is there any "disconnect" event?
I am using nestjs server and react with apollo-link-ws
Thank you all.

Related

How many websocket subscribtions should i have in a messenger app?

I develop a backend part of a messenger thing of some project. And i'm wondering what whould be the best way to provide websocket stomp subscriptions to frontend.
Pseudo event list:
message delivered
message edited
chat created
user typing
etc.
should it be like:
users/id/messages/created
users/id/messages/edited
users/id/chats/created
(One subscription per event)
or:
users/id/messenger/events
and json message with EvenType to define an event

Is there a way to send the data from the web form to the microsoft botframework web client without opening the web client?

We have a Angular application with .Net core.
When the users type on the input from their web page form field, it will need to be passed to the Microsoft BOT framework.
The response message from the BOT service will need to be displayed back to the Bot Chat client.
Users will review the above response and have the ability to send the received data from Bot Client back to the web page form fields.
I have read about the Web chat client and the Direct Line bot.
I can use Web chat client but I am not sure how to pass the input from my web form to it as I don't want the user to open the web chat to enter the same data again.
If I use the Direct Line Bot, I have control on passing the form input to the Bot service. In this case, I will need to spend time to build the Web client to display and process the messages.
You can do this by utilizing the DirectLine connection instance that you give to the WebChat control when you create it. The connection instance will enable you to both send events into the bot as well as watch for events coming out of the connection. At the same time, since you're sharing the connection with the chat control, the chat control can perform its typical duties of sending and receiving/displaying message contents.
For example, when the user clicks on the submit button on your form, you would utilize the connection object to send an event that contains your payload like so:
Setup DirectLine connection
Create the DirectLine connection at start up and assign it to your WebChat control, but also hold onto the connection object in a variable you can utilize in other places such as the form button click.
const directLineToken = await getDirectLineToken();
const directLineConnection = createDirectLine({ directLineToken });
Form button click logic
In the form button click logic you can now send an event activity that represents your proprietary backchannel event to the bot containing the form details as the payload:
const fancyFormEventPayload = {
fieldA: fieldAFormElement.value,
fieldB: fieldBFormElement.value,
// etc
};
// NOTE: this returns an observable that you can wait on
// to watch for errors or know when it has completed. I'm
// just using fire and forget here for now
directLineConnection.postActivity({
type: "event",
name: "myFancyFormSubmitted",
value: fancyFormEventPayload,
});
Listening for events coming back
Now the bot might respond with some message activities which the WebChat would then display, but it could also send back an event activity that contains the updated form payload which you could watch for and grab to populate the form with the updated values if they say "yes" for that.
// The connection exposes the stream of incoming activities via Rx, so
// we create filtered subscription that will process only the activity
// we're interested in and update the form fields in response to that
directLineConnection.activity$
.filter(activity => activity.type === 'event' && activity.name === 'myFancyFormUpdate')
.subscribe(activity =>
{
const myFancyFormPayload = activity.value;
fieldAFormElement.value = myFancyFormPayload.fieldA;
fieldBFormElement.value = myFancyFormPayload.fieldB;
// etc
});

Spring STOMP - immediate response

I am implementing an Angular client that connects to a spring boot backend via STOMP.
When a client connects and wants to create a "business-group", said group is created in the backend and gets a UUID; and from that moment on other clients should be able to send to and receive messages from that group.
So I am creating a topic with said business-group id in the destination - something like
#MessageMapping("/foo/group/{id}")
However I want the creator of the group to immediately receive the business group id to be able to subscribe to it himself as well. And to be able to share the id with others (user to user).
I have used raw sockets for this before, so I was able to just use the connected user's session and then send back the id to him after the had sent the create-message. But since the session handling was business-group-ID based (so that only the users in a specific group receive the messages from that group), the whole dividing user sessions by business-group-ID had to be done manually and I was looking to upgrade this to something that does that handling for me.
However I am not sure how to achieve this with spring stomp. So my question is, is there a way for the creator of such a group to immediately receive the id as an answer/response to his initial "request"?
Because he can't subscribe to anything before he receives the group id.
Background:
It's basically like a chat app where a user can create a group/chatroom and then share it with others (via URL - which contains the ID); everyone that subscribes to it can then receive msgs from it and send msgs into it. But to do so the creator first needs the created ID.
I found a solution. This can be done via #SendToUser
#MessageMapping("/group.create")
#SendToUser(value="/topic/group.create", broadcast=false)
public Response createGroup(#Payload Message message) {
...
return createResponseWithId();
}
On the other end you only need to subscribe to '/user/topic/group.create'.

Sending Private Messages to Users using Socket.IO

I am new to Sails and Socket.IO currently I am building an chat application where users can send private messages to each other. I manage to build a basic chat application but it broadcast updates to all users who are connected to Sails application.
Could you please suggest me a way to send messages to particular user which connected to the sails application.
Thanks
Sails incorporates Socket.io without changing it a lot, so you can use standard Socket.io tools within Sails.
In your particular case we are probably talking about rooms functionality.
try
let isSocket = req.isSocket
if(isSocket) {
let id = sails.sockets.id(req.socket)
sails.sockets.emit(id,'privateMessage',{payload:"hello"})
}

How to dynamically create a new a Topic using Events Push plugin

To create a topic for an event I need to declare this in my conf/MyEvents.groovy file as follows:
events = {
"topicName" browser: true
}
I am wanting to use the server push for two things, pushing chat messages to a client and also for pushing notifications to a client.
Using the former as an example, I will need to create a new Topic for each conversation that is instantiated in the chat system at runtime, so that messages can be pushed to each of the conversation participants, so along the lines of
new Event(topic:'anotherTopicName',...)
which will allow me to call from a service :
import grails.events.*
class MyService {
def doSomething(){
...
event(topic:'anotherNewTopic', data:data)
}
}
Is there a method that will allow me to create a new Event topic? Or is there another way to implement this using Events Push
I've just done something similar. I needed to show some notifications based on the user that had logged in, so I set this in MyEvents.groovy:
events = {
'newNotification_*' browser:true
}
And when I need to send the notification:
event topic:"newNotification_${userId}",data:n
Then in my browser I can listen to those notifications with something similar to this:
grailsEvents.on("newNotification_"+myUser,function(data){

Resources