I am working with a Backbone front end, and we are currently making it realtime with the use of pusher. Most of the events are triggered from our API and then we listen to them on channels in our backbone front end.
However there is situation where we want to update a view for all subscribers to a channel on a button click, there is no server interaction here and we would like to keep is this way.
I have read the documentation for pusher, and it sounds like what we want is a client event, but from what I have read it sounds like this needs to be authenticated request...however by the virtue that the user is using the application means they have been authenticated.
Is there a way to broadcast an event from a client and not need a private channel or to authenticate?
There is not. If there were then anyone would be able to connect to Pusher independently of your application and publish arbitrary client events to your users.
Without the authentication provided by a private channel, it's not necessary to be using your application to join your channels. All that is required is your App ID, which is the equivalent to a username - that is to say, it should be considered public knowledge.
The same goes for broadcasting to public channels from your server. They really are public, if you want to restrict the audience to authenticated users of your app, you should use private channels.
Related
I have searched long and far. I am typically familiar with the LAMP stack so apologies - I am learning Node as I'm trying to build a chat feature - similar to how Intercom/drift would work.
I have been led to believe that Socket.io is a good way to go about this, and I am having a little bit of trouble. The basic overview is something like this:
Users can use my service to have a live chat feature enabled on their websites (they each have a unique API key)
They can add the chat to any number of web pages/domains (via a script tag)
The chat should be private between any single end user of the website, and the admin of the script tag (owner of the API key used to include the script on the page)
I'm having trouble with this.
Should I create dynamic namespaces for each URL, or is it a room?
Lets say I create a dynamic room on the client side that is unique such as is used in https://stackoverflow.com/a/19150254/1173155
// client side code
var dynamicRoomName = API_KEY + "_" + fullURL + "_" + expressSessionId;
var socket = io.connect();
socket.emit('create room', dynamicRoomName);
// server side code
io.sockets.on('connection', function(socket) {
socket.on('create room', function(room) {
socket.join(room);
});
});
The only person who should be able to see this chat other than the end user is the admin of that API Key, which I'm not sure how to implement.
I realise I will likely need a DB of some sort to keep track of the chats/rooms ect. Is there any good resource on how to learn how to implement this kind of thing?
Help is much appreciated!
Just going to expand a small bit on this, perhaps for my own good while working on the problem.
There can be many admins (unique APIs)
Admins are responsible for only their own chats - they cannot see any chats that do not belong to their API key
Many users can chat with one admin (in private)
All chat is 1 to 1
The end user and the admin user will thus use different clients
Admin can be in numerous chats to individual users
Users would typically be in one chat to one admin
Admins can't create chats (only receive incoming) - but of course can reply
I don't think you want to use a namespace because then your server would have to be pre-listening on the server to every possible namespace in order to hear a connection to it. That seems impractical and inefficient. There are a number of different possible schemes. Here's one I think is fairly simple to implement.
You create one namespace for this admin chat.
Your server listens to that namespace and accepts incoming connections to it.
The client connects to that namespace when they want the chat with the admin.
The client then sends an initiateChat message with the API_KEY as data.
The server is coded to not accept any other messages until initiateChat has been received with a valid API_KEY
When the server receives the initiateChat message, it looks up the API_KEY in your database and if it finds it in the database and that user is currently online, it starts a chat session with them. If they are not currently available, it sends a message back to the client indicating they are not currently online.
Now the socket is open for chat related messages.
You can use a dynamically created room name to keep track of the two end points if you want and join both sockets to that room.
If the admin user can be involved in multiple chats with the same socket, then you will have to make sure the chat messages it sends are labeled with which chat they belong to so you know which room name to send the message to on your server.
i'm experimenting node.js and made a cool chat application followed by this article using socet.io!
Then i have added a authentication system using Passport.Js into my test site.
How i would do this: among many users, user X want to send some kinds of notification to user Y not to other users!!
I am using the emit() function with a custom event called notifybuzz
but when a user send a notification it goes to all accounts!!
This article mentions that you will need to use the form socket.broadcast.emit('hi'); to send to limited recipients. the challenge will be to keep track of your socket connections, and relate user information to them. Once that's done, you'll know exactly which socket to send your message over.
Best of luck!
I am building a multiplayer turn based game, the communication between clients and server is established with Pusher. I can send events to all clients using game channels. The problem is how do I send an event to a single client? Pusher has no documentation for it, only seemingly solution is to use authenticated channels. Is it viable to authenticate a dedicated channel for every client sending events to a single client, or is there a better solution?
You touched on the best solution in your answer. You should be able to quite easily programmatically setup channels for each individual user and then just broadcast messages to them over those channels.
e.g. (this is a Ruby example but it should be clear what's happening)
user = SOME_USER_OBJECT
Pusher.trigger("card-data-#{user.id}", 'card-update', {data: {card_id: 1, status: 'used'})
or something like that. Obviously you'd then need to make sure that on the client side that the users are subscribing to the correct channels.
Obviously if you need the channels to be secure then, as you said, you can use authenticated channels - probably using private channels makes sense in your case.
If you have any more questions then you can reply here again and I'll take a look, or you can email support at support#pusher.com.
Instead of creating an individual channel you can subscribe to an individual event for each client.
PubNub Stream Filter
If you are using PubNub, you can either create a unique channel for each user and just publish the proper message to each of the channels or you can create a common channel for all of the users and use the Stream Filter feature so that each client only gets messages they want on that channel. This filtering is performed on the server side so the end user doesn't get unwanted messages that have to be ignored.
This is the simple high level steps for using Stream Filters
When you init PubNub on the client side, create a filter using the meta parameter
When you publish messages, add key/values to the meta parameter that will be used to filter messages on the PubNub Network before sending them to the subscribers (based on each individual subscriber's filter).
For full Stream Filter docs per SDK (that you mentioned via tags):
PubNub JavaScript SDK Stream Filter
PubNub Node SDK Stream Filter
PubNub Ruby SDK Stream Filter
You could also use PubNub BLOCKS to route each message to the appropriate user channel (or however you map your channels to end users) the on before publish event handler. I won't go into the details of this since it is slightly more involved but feel free to ask for additional insights as necessary. To get started, you can review the full BLOCKS docs.
Been researching heaps and making no progress :(
Trying to set up a small web app using VB in VS 2013.
I have added all the SignalR resources to my project.
Each logged in client has a UserID in my database.
I want to invoke a SignalR message to certain UserID's from server-side code, not client-side. Firstly, is this possible? (it was possible using ReverseAJAX, but I have chosen not to use that)
If it is possible, how do I go about setting up the SignalR Hub to allow me to send a message using a UserID? I don't need help with the SQL, I can do that my self.
Also, what javascript do I need to persist the request? I'm guessing I will need the UserID somewhere in this piece of code.
Thanks heaps.
This is very possible. If you look here
http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-server#callfromoutsidehub
you will find a section on "Single User Groups". This is the mechanism available in version 2 to send a message to a single User Id. Essentially when a Connection is established you add the User Id to a "group" which can be accessed by Group Name (syn. User Id) without having to worry about persisting the relationship of a connection id to a user id yourself. The only limitation would be if more than 1 connection is established by the same user, all devices with that user would be in the same group and would therefore receive any messages sent to it...
There is also another section on how to retain the instance of your SignalR context on the web server to make calls out to clients (How to call client methods and manage groups from outside the Hub class)
I did read something about the SignalR team creating User Id methods but I have used the above approach with fair success and haven't looked much further into that.
Hope this helps
As #Pepto mentioned, here it is described how you can get a reference to your hub, and then use it in your server code.
An easy way to invoke a client-side function for a specific user, would be to use Clients.User("Username") in your hub.
Intellisense will tell you that User() wants an ID as a parameter, but you should pass the username of the user, whose function you want to invoke, not his ID.
I have a Backbone application which handles public and private stuff.
Public => Login, Registration, News, etc.
Private => Chatting, other user specific information.
To secure the entire application I have a session-based authentication mechanism in node.js. This mechanism secures the backend-api. Now the question is how I can secure the front-end.
How do I secure routes in Backbone
How could I secure modules (requireJs) in Backbone
One idea I had was to split up the front-end into public and private and the server decides if it grants access to the private-assets.
What other front-end-secure concepts are out there?
To make it more specific:
I want to check client-side if the user is authenticated and I want to restrict loading require-js modules to unauthenticated people (to save bandtwitch)
your server should provide an API to check if the current user (possibly via their cookies) it authenticated.
In backbone, on your routes/navigations you can check to see if your user is authenticated and then execute code or not (probably calling a requireJS module after the auth check).
To my knowledge there is no backbone thing that has the concept of user state. You could implement a setTimeout loop to request the auth state from your server, and then implement Backbone.Events on top of that to emit an event when the user is no authed, which your backbone app could listen to and then trigger the rendering of a login view, or route the user to a login page.
I mainly user couchdb for my backend, and it has a $.couch.session function that will let me know of the state of the current user's auth. you will most likely need to implement your own session function that hooks into your backend framework.