Pusher: How to get private channel subscription count in pusher? - javascript

What I want: How can i get subscription count after subscription of a private channel in pusher.Actually i want private chat between only 2 users.
What I Know and Doing: . I know that i private channel can be subscribed by multiple clients(users).So whenever server trigger the data to private channel then all subscribed user get that response.
Channel subscription code in java script (Client-1):
<!DOCTYPE html>
<head>
<title>Pusher Test</title>
<script src="https://js.pusher.com/3.2/pusher.min.js"></script>
<script>
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
var pusher = new Pusher('PUSHER_KEY', {
authEndpoint: 'http://localhost:8080/medecube/rest/initial/pusher/auth',
auth: {
headers: {
'X-CSRF-Token': "12345"
}
}
});
var channel = pusher.subscribe('private-channel');
channel.bind('pusher:subscription_succeeded', function() {
var triggered = channel.trigger('client-myEvent', { "message": "i am pusher client1" });
});
</script>
</head>
Same channel subscribed by client 2
Channel subscription code in java script (Client-2):
<!DOCTYPE html>
<head>
<title>Pusher Test</title>
<script src="https://js.pusher.com/3.2/pusher.min.js"></script>
<script>
// Enable pusher logging - don't include this in production
Pusher.logToConsole = true;
var pusher = new Pusher('PUSHER_KEY', {
authEndpoint: 'http://localhost:8080/medecube/rest/initial/pusher/auth',
auth: {
headers: {
'X-CSRF-Token': "12345"
}
}
});
var channel = pusher.subscribe('private-channel');
channel.bind('pusher:subscription_succeeded', function() {
var triggered = channel.trigger('client-myEvent', { "message": "i am pusher client2" });
});
</script>
</head>
Event Trigger by server:
Pusher : Event recd : {"event":"client-myEvent","data":{"message":"i am pusher client2"},"channel":"private-channel"}
Then both client get same response. I want only one user subscribe only 1 channel.

It is possible to get subscription count for private channels, you don't have to use a presence channel. However, to get subscription count for a private channel you have to explicitly enable that feature via your Pusher dashboard as it's not enabled by default:
https://pusher.com/docs/rest_api#method-get-channel

You need to use presence channels to get information about the members in a channel. In your case you could get the count of subscribers with var count = presenceChannel.members.count;.

Related

How to connect to a node server from a button press?

Can I connect to a nodejs server with socket.io from a button press? I got my page for example file:///home...site/index.html and a server running on my local machine for example localhost:8080. Can i connect to the server from my file with when i call a function, using xmlhttprequest or other means? How? Got links/tutorials?
I have a very simple socket.io example on GitHub: socketio-example
Update the index.html page in this example to look like this:
<!doctype html>
<html>
<head>
<script src='/socket.io/socket.io.js'></script>
<script>
var socket;
function makeConnection() {
socket = io();
socket.on('welcome', function(data) {
addMessage(data.message);
// Respond with a message including this clients' id sent from the server
socket.emit('i am client', {data: 'foo!', id: data.id});
});
socket.on('polo', function(data) {
addMessage(data.message);
});
alert('connected.');
}
function addMessage(message) {
var text = document.createTextNode(message),
el = document.createElement('li'),
messages = document.getElementById('messages');
el.appendChild(text);
messages.appendChild(el);
}
function marco() {
socket.emit('marco');
}
</script>
</head>
<body>
<button onclick="makeConnection()">Connect</button>
<button onclick="marco()">Marco!</button>
<ul id='messages'></ul>
</body>
</html>
This will establish the socket.io connection when the user clicks Connect. Then you may click Marco! to send a message and receive the Polo! response.

Receiving Messages From Websocket Scala

I'm trying to configure a WebSocket in Scala. I have a function that broadcasts a bunch of JSON to a WebSocket. It works when I configure it through http://www.websocket.org/echo.html (inputting my own ws://localhost:9000/web-socket), but I need it to display the information on a new webpage.
To that effect I made a new webpage called client which is defined in my controllers as
def client = Action {
val data = new RedshiftData() // get the data
Ok(views.html.client(data))
}
In my views I have client.scala.html defined as (adapted from websockets.org)
#import datadump.RedshiftData
#(data: RedshiftData)
<!DOCTYPE html>
<html>
<script>
var wsUri = "ws://localhost:9000/web-socket";
var ws = new WebSocket(wsUri);
#data.pushToWebSocket
ws.onmessage = function (evt) {
var msg = JSON.parse(evt.data);
console.log(msg);
};
</script>
<body>
</body>
</html>
But, it never receives my message that I'm sending. How do I get it to listen to the message that I send out in the controller?

Google Sign In not being signed in when page refreshes (Polymer)

I'm implementing "Google Sign In" into my website to handle all user authentication etc.. I will have a back-end database that I use to store information against users to keep track of their profile and their actions etc..
I've followed the Google Developer documentation and have got a "Google Sign In" button on a web page and when this button is clicked I choose my account and am signed in and the id_token goes off and is authenticated with my back-end server successfully. The only problem I'm now having is that when I refresh the page the button is back to "Sign In" rather than staying signed in, is this normal behaviour or is there something I'm missing? I don't want users to have to have to sign in again whenever the page changes.
On a side note I have managed to store the id_token from successfully logging into Google in localStorage and then using this id_token to re-authenticate with the back-end server automatically (as you can see in the commented out code) but this doesn't obviously automatically change the status of the "Google Sign In" button which would confuse users on the client-side.
Can anyone shed any light on this problem please?
Not signed in:
After signing in (doesn't currently stay like this after a page refresh):
login.html:
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="./css/base.css"/> <!-- Base CSS -->
<script src="./js/all.js"></script> <!-- All JavaScript file -->
<script src="./js/Logger.class.js"></script> <!-- Logger class -->
<script src="./bower_components/jquery/dist/jquery.min.js"></script> <!-- jQuery -->
<script src="./js/gSignIn.js"></script>
<!-- Polymer -->
<script src="./bower_components/webcomponentsjs/webcomponents-lite.min.js"></script> <!-- Web Components Import -->
<!-- Element Imports -->
<link rel="import" href="./bower_components/paper-button/paper-button.html"/>
<link rel="import" href="./bower_components/google-signin/google-signin.html"/>
</head>
<body>
<google-signin id="gSignIn" client-id="--- REMOVED FOR PRIVACY ---" scopes="profile email openid"></google-signin>
Sign Out
</body>
</html>
gSignIn.js:
/**
* Google Sign In JavaScript
*/
$(document).ready(function() {
var logger = new Logger("gSignIn.js", false); // logger object
var id_token = null;
logger.log("Load", "Successful");
// Try to automatically login
// if (localStorage !== null) { // If local storage is available
// if (localStorage.getItem("gIDToken") !== null) { // If the Google ID token is available
// id_token = localStorage.getItem("gIDToken");
// // Send off AJAX request to verify on the server
// $.ajax({
// type: "POST",
// url: window.api.url + "googleauth/verify/",
// data: { "id_token": id_token },
// success: function (data) {
// if (!data.error) { // If there was no error
// logger.log("Google SignIn", "Successfully signed in!");
// }
// }
// });
// }
// }
/**
* EVENT: Google SignIn success
*/
$("#gSignIn").on("google-signin-success", function () {
id_token = getGoogleAuthResponse().id_token;
var profile = getGoogleProfile();
console.log("ID: " + profile.getId()); // Don't send this directly to your server!
console.log("Name: " + profile.getName());
console.log("Image URL: " + profile.getImageUrl());
console.log("Email: " + profile.getEmail());
// Send off AJAX request to verify on the server
$.ajax({
type: "POST",
url: window.api.url + "googleauth/verify/",
data: { "id_token": id_token },
success: function (data) {
if (!data.error) { // If there was no error
logger.log("Google SignIn", "Successfully signed in!");
// Store the id_token
if (localStorage !== null) { // If localStorage is available
localStorage.setItem("gIDToken", id_token); // Store the id_token
}
}
}
});
});
$("#signOut").click(function () {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log("User signed out.");
});
});
/**
* Get Google Profile
*
* #returns object
*/
var getGoogleProfile = function () {
var profile = gapi.auth2.getAuthInstance().currentUser.get().getBasicProfile();
return profile;
};
/**
* Get Google Auth Response
*
* #returns object
*/
var getGoogleAuthResponse = function () {
var response = gapi.auth2.getAuthInstance().currentUser.get().getAuthResponse();
return response;
};
});
Thanks!
I had the same problem and, after ensuring third party cookies were enabled, it came down to the hostname, localhost in this case.
In the end, I had to fake a domain using /etc/hosts, ensure google developers dashboard has that domain whitelisted, and start using that domain instead of localhost.
I can only assume that gapis don't like localhost, even though it's whitelisted in my google developers dashboard for the account I'm using. If you do manage to get localhost to work, do give me a shout!
Another way to do this is to access localhost from a nonstandard port (not 80). I managed to get around this headache by using an nginx proxy from port 80 to 81:
server {
listen 81;
location / {
proxy_pass http://localhost:80;
}
}

Implementing WebSockets using SignalR

I'm trying to use websockets into my ASP.NET MVC web-app but I can't implement, so here I'm trying to display each database update on the end-user web-page without any need to refresh.
HTML:
<span id="nbAlertes"></span>
<ul id="listeAlertes"></ul>
Javascript / SignalR / jQuery
<!--Reference the SignalR library. -->
<script src="Scripts/jquery.signalR-2.0.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="signalr/hubs"></script>
<script>
$(function () {
// Declare a proxy to reference the hub.
var alertes = $.connection.AlerteHub;
// Create a function that the hub can call to broadcast messages.
alertes.client.broadcastMessage = function (nbAlertes, listeAlertes) {
// Html encode display name and message.
var nbA = $('<div />').text(nbAlertes).html();
var lstA = $('<div />').text(listeAlertes).html();
// Add the message to the page.
$('#nbAlertes').text(nbA);
lstA.forEach(function(item) {
$('#listeAlerte').append(item.nomPoste);
});
};
});
</script>
class AlerteHub:
public class AlerteHub : Hub
{
public void GetAll()
{
var nbAlertes = new CalculAlertesUtilitaire().compter();
var listeAlertes = new CalculAlertesUtilitaire().lister(5);
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(nbAlertes, listeAlertes);
}
MonitoringNDataContext _db = new MonitoringNDataContext();
public string compter()
{
var compte = _db.Alertes.ToList().Count();
return (compte == 0) ? "" : compte.ToString();
}
public ICollection<AlerteModel> lister(int nb)
{
return (ICollection<AlerteModel>)_db.Alertes.ToList().Take(nb).ToArray();
}
}
class Startup
public class Startup
{
public void Configuration(IAppBuilder app)
{
// Any connection or hub wire up and configuration should go here
app.MapSignalR();
}
}
How do I to make it work, please ?
If you want to use SignalR, you need to establish the connection on the client. In JavaScript you do this by calling connection.start(). For example:
<!--Reference the SignalR library. -->
<script src="/Scripts/jquery.signalR-2.0.2.min.js"></script>
<!--Reference the autogenerated SignalR hub script. -->
<script src="/signalr/hubs"></script>
<script>
$(function () {
// Declare a proxy to reference the hub.
var alertes = $.connection.alerteHub;
// Create a function that the hub can call to broadcast messages.
alertes.client.broadcastMessage = function (nbAlertes, listeAlertes) {
// Html encode display name and message.
var nbA = $('<div />').text(nbAlertes).html();
var lstA = $('<div />').text(listeAlertes).html();
// Add the message to the page.
$('#nbAlertes').text(nbA);
lstA.forEach(function(item) {
$('#listeAlerte').append(item.nomPoste);
});
};
$.connection.hub.start().done(function () {
// You should probably be calling GetAll from somewhere.
// I'm not sure if you should call it as soon as you connect,
// but you certainly can't call GetAll before connecting.
alertes.server.getAll();
}).fail(function (error) {
alert("Failed to connect!");
});
});
</script>
You can learn more about how to use the Signalr JS client here: http://www.asp.net/signalr/overview/signalr-20/hubs-api/hubs-api-guide-javascript-client

Google-App-Engine Channel API: Server doesn't send message to client

I've created simple code to understand, how Google App Engine Channel API works. However, actually my code doesn't work and I dont know why. I am not very experienced in Python so pardon me, if it will be some stupid mistake.
Server:
from google.appengine.api import channel
import webapp2
import jinja2
import os
import time
channel_key = 'key'
class MainHandler(webapp2.RequestHandler):
def get(self):
token = channel.create_channel(channel_key)
template_values = {'token': channel_key}
template = env.get_template('index.html')
self.response.write(template.render(template_values))
class OpenedHandler(webapp2.RequestHandler):
def post(self):
channel.send_message(channel_key, "hi")
env = jinja2.Environment(loader=jinja2.FileSystemLoader(os.path.dirname(__file__)))
app = webapp2.WSGIApplication([
('/', MainHandler),
('/opened', OpenedHandler)
], debug=True)
Client:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
var token = "{{ token }}";
onOpened = function() {
var xhr = new XMLHttpRequest();
xhr.open('POST', '/opened');
xhr.send();
};
onMessage = function(message) {
alert("something recieved");
alert(message);
}
</script>
<script type="text/javascript" src="/_ah/channel/jsapi"></script>
<script>
channel = new goog.appengine.Channel(token);
socket = channel.open();
socket.onopen = onOpened;
socket.onmessage = onMessage;
socket.onerror = function(e){
alert("error:"+e['description']);
};
socket.onclose = function(){
alert("close");
};
</script>
</body>
</html>
Javascript console says, that it was successfully sended to /opened, but then no alert comes, like it havent responded.
Do you have any idea, where the problem is?
Thanks Toneks
EDIT: I added onerror and onclose event handlers to javascript and immediately after opnening the page it calls onerror event saying "Invalid+token" and then onclose event.
I'll bet if you log your channel_key it'll be different when you create the channel and when you send the message. For this exercise you could just use a constant; for "real" code you'll want to use the datastore and memcache for your channel keys.

Categories