Pusher Private Channel Subscription Succeeded Callback Data - javascript

I am trying to get the data sent back from the server, after connecting to a private Pusher channel. The following code works for a presence channel:
this.presenceChannel = this.pusher.subscribe('presence-chat');
this.presenceChannel.bind('pusher:subscription_succeeded', function(data){
//I can access all of the data here as expected
console.log(data);
});
But when I try the same approach with a private channel:
this.privateChannel = this.pusher.subscribe('private-user');
this.privateChannel.bind('pusher:subscription_succeeded', function(data){
//This returns an empty Object {}
console.log(data);
});
The interesting thing is, in the POST request data I can see the data that I am trying to access, but I can't figure out why I can't access it like I can for presence channels:
{"auth":"a146722cb55df886314f:7326fb3e1c807a679b4d4d5e5742fddc121d5ec18f5f078d054962b0267972a4","channel_data"
:"{\"data\":\"test\"}"}

try binding to this event instead
'pusher_internal:subscription_succeeded'
The pusher:subscription_succeeded event is triggered following the receipt of a pusher_internal:subscription_succeeded event. The different event name is used to differentiate a public event from an internal one.

Related

How to use socket after connect event in socket.io?

sorry for my english.
There is a problem. Inside my app.js server, I added sockets, I use the join event, inside 'connection' event is a function that takes a socket as a parameter, however, I want to push the user into a room, but the name of this room is available inside the model of my REST API part of the server (from the session).
Question. How can I take and push a user who has connected to the right room inside my REST API model? (this model and its service are fired whenever a user requests a page, let's say an analogue of an authorization check). In addition to this problem, there is another service and model that are responsible for adding, for example, some kind of task, this is also a REST API, and so inside this model I would like to send messages to all the necessary users in sockets that a task has been added, EXCEPT the sender himself At the moment I can't do anything at all. It is sent to everyone in general, including the sender, the socket from the connection cannot be thrown in the REST API model
App.js
io.on('connection', (socket) => {
app.set('socket', socket);
socket.on('disconnect', () => {
socket.disconnect(true);
});
});
Controller that sends data to all services, and those in the model
const controller = (ServiceClass, params) => {
return async (req, res, next) => {
const service = new ServiceClass({
session: req.session,
sessionId: req.sessionID,
cookies: req.cookies,
socketIo: req.app.get('socketio'),
socket: req.app.get('socket'),
});
const response = await service.run(params(req));
res.json(response);
};
}
export default controller;
Inside the model that fires on every request to the site from the user, here I'm trying to give the right room
export default class IsLoggedService extends Service {
constructor(context) {
super(context);
}
async execute() {
this.context.socket
.join(`room${userSession.roleId}`);
}
}
I send information to the client about the created task also from the rest api service + model
this.context.socket
.to(`room${userSession.roleId}`)
.emit('test', 'test');
I have already reviewed the entire socket.io documentation, it says everywhere that in order to send a message to everyone except yourself, you need to use a socket, but this does not work at all, it is sent to everyone, including the sender, I also tried to achieve a socket inside the service and model, all to no avail
The most logical implementation method is that you receive all the user through the json object that you receive when sending a message through the socket and implement the logic of the program according to the data.

How to send broadcast data with Web Socket Server?

I need to send data from my BE to FE when an event happen, so I have created an Event Emitter and in the Fucntion i would like to send a Broadcast message to all the client (the message is an Array of Object), this is my code but unfortunately doesn't work properly.
emitter.on('readData', function(){
wss.broadcast = function(data) {
wss.clients.forEach(client => client.send(Object));
};
});
Ok instead of broadcasting, you are defining a function to broadcast.
emitter.on('readData', function(){
wss.clients.forEach(client => client.send(Object));
});
More details here.

JavaScript - How to create custom API listener for Socket.io events?

i'm trying to create custom API listener for 3-rd developers on my site. It should look like this:
// Function will be fired when any user joins to room
API.on('user-join', function(data){
console.log(data); // Data is object with user id and name
});
I have Socket.io listener too:
// This handler is fired every time when anyone joins
socket.on('user-join', function(data){
// Probably here i should call a callback to API.on('user-join') with that data object
});
How can i send callback in Socket.io handler to my custom created API? Please let me know how to do this. Thanks.
Not sure what you are trying to do, but if I understand correctly, you want to map the "on" function of the socket.io API to your API.
The best way to do this would be to implement a function like this:
API.on = (eventName, callback) => {
socket.on(eventName, callback);
}
Where eventName is a string and callback a function.
This way, you can add an event listener to your API, the same way you would with Socket.io
Eg:
API.on('testEvent', (obj) => {console.log(obj});
you are mixing things up.
your socket API will need a server-side listener independent from your socket API, that, as far as i understood, manages the IO with the connected clients, am i right?
In this case, you don't have to bind anything. You need a controller for your API sockets and your client's controller have to trigger events to those users.
a client connects to your site
a notification is received by the server
the server notifies to the API users
here's some pseudocode, please don't use it, it just illustrates a concept :D
const thrdUsers = [.....] // socket connections
const onThirdUserConnects = socket => thrdUsers.push(socket);
API.on('connect', onThirdUsersConnects);
// Then you need a broadcast function to send events to all your clients
const broadcastToAPI = (msg, val) => thrdUsers.forEach(s => s.send(msg, val));
// Your users will trigger events to your socket.io service
socket.on('whatever-event', (data) => {
//...Do stuff
// notify the API clients
broadcastToAPI('whatever-event', data);
});

Why is my Service Worker's push event data/payload null?

I have made multiple attempts to get desktop notifications working in Chrome, but I have not found a single source of documentation that covers a step by step procedure to get desktop notifications to work correctly. Each resource I have come across is either outdated or inconsistent with others.
The problem I am facing is: once the Service Worker receives the push event,
self.addEventListener('push', function (event) {
console.log(event);
event.waitUntil(
self.registration.showNotification(
event.data.title,
{
body: event.data.body,
icon: event.data.icon,
tag: event.data.tag
}));
});
event.data is null. I expect it to have data that I am sending as JSON in a POST request like this:
POST https://fcm.googleapis.com/fcm/send HTTP/1.1
Content-Type: application/json
Authorization: key=<FCM Server Key here>
{
"data": {
"title": "Foo",
"body": "Bar"
},
"to": "<recipient ID here>"
}
The weird thing is the registration script gets a "subscription endpoint" that looks like https://android.googleapis.com/gcm/<recipient ID here>, but I cannot get the POST to go through unless I follow other examples on the web that say to put the recipient ID as the to field in the JSON I am sending.
Of all the examples I have come across, there are multiple URLs that POST calls are being made to:
https://fcm.googleapis.com/fcm/send
https://android.googleapis.com/gcm/send
https://gcm-http.googleapis.com/gcm/send
I have tried all three, with each attempt having the recipient at the end of the API address (like https://fcm.googleapis.com/fcm/send/<recipient ID here> and alternatively in the JSON body. My goal is to get Foo and Bar from the data I am sending into the self.registration.showNotification( method of the service worker.
Why is event.data null? Can anyone point me to a complete guide from start to finish that favors FCM over GCM? Any help would be appreciated.
You may want to check the following statement from the documentation,
A downside to the current implementation of the Push API in Chrome is that you can't send any data with a push message. Nope, nothing. The reason for this is that in a future implementation, payload data will have to be encrypted on your server before it's sent to a push messaging endpoint. This way the endpoint, whatever push provider it is, will not be able to easily view the content of the push message. This also protects against other vulnerabilities like poor validation of HTTPS certificates and man-in-the-middle attacks between your server and the push provider. However, this encryption isn't supported yet, so in the meantime you'll need to perform a fetch to get information needed to populate a notification.
Reading further, you may want to try using fetch() to get data from an API, convert the response to an object and use it to populate notification. This same method was also used in this related SO post.
In addition to that, you may want to also check the response of #Indici Indici in the thread wherein he stated that push event does not contain data values; instead it contains different events which contains information(s). Here is the sample code that was provided as a possible workaround to receive notification in Firebase service-worker in "push" event:
self.addEventListener('push', function(event) {
if (event.data) {
const dataText = event.data.text();
notificationTitle = 'Custom Notification';
notificationOptions.body = 'Message: ' + `${dataText}`;
var title = event.data.notification.title;
var message = event.data.notification.message;
var icon = event.data.notification.icon;
var notificationTag = event.data.notification.tag;
}
}
For receive data need:
self.addEventListener('push', function(event) {
var jsonData = JSON.parse(event.data.text());
// jsonData -> here is you data
const options = {
body: 'set you body',
icon: 'img/apple-icon-120x120.png',
badge: 'img/apple-icon-120x120.png'
};
event.waitUntil(self.registration.showNotification(jsonData.data.title, options));
});

Socket IO send to specified user ID

I want to send data to the specified user, and no one else.
currently to broadcast to everyone I do:
socket.on('newChatMessage', function (message) {
socket.broadcast.emit('newChatMessage_response', { data: message});
});
now what I want to do is simply something like:
socket.on('newChatMessage', function (message) {
socket.to(5).send('newChatMessage_response', { data: message});
});
to(5) would be the user with the ID of 5.
I think the missing piece for you is inside this function: io.sockets.on('connection', function(socket) { ... });- That function executes every time there is a connection event. And every time that event fires, the 'socket' argument references a brand new socket object, representing the newly connected user. You then need to store that socket object somewhere in a way that you can look it up later, to call either the send or emit method on it, if you need to send messages that will be seen by only that socket.
Here's a quick example that should get you started. (Note: I haven't tested this, nor do I recommend that it's the best way to do what you're trying to do. I just wrote it up in the answer editor to give you an idea of how you could do what you're looking to do)
var allSockets = [];
io.sockets.on('connection', function(socket) {
var userId = allSockets.push(socket);
socket.on('newChatMessage', function(message) {
socket.broadcast.emit('newChatMessage_response', {data: message});
});
socket.on('privateChatMessage', function(message, toId) {
allSockets[toId-1].emit('newPrivateMessage_response', {data: message});
});
socket.broadcast.emit('newUserArrival', 'New user arrived with id of: ' + userId);
});
Edit: If by id you're referring to the id value that socket.io assigns, not a value that you've assigned, you can get a socket with a specific id value using var socket = io.sockets.sockets['1981672396123987']; (above syntax tested using socket.io v0.7.9)
It's hard to say exactly how to do this without seeing your full code, but it sounds like you want to call the emit method on the individual socket you're trying to send to. If this is different from the socket making the connection (ie., a private chat partner) then you'll need some other way of storing and retrieving the correct socket you're trying to communicate with.
var sck = someFunctionToGetAppropriateSocketObject();
sck.emit('newChatMessage_response', { data: message});
see http://socket.io/#how-to-use and https://github.com/learnboost/socket.io

Categories

Resources