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.
Related
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.
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;.
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?
I have the following html/javascript code that uses websockets to communicate with a server. It seems like I can only send(message) only inside the onmessage() and onopen() functions. How can I send data outside of those functions ?
<!DOCTYPE HTML>
<html>
<head>
<script type="text/javascript">
function WebSocketTest() {
if ("WebSocket" in window) {
var ws = new WebSocket("ws://localhost:57252/");
ws.onopen = function () {
ws.send("Hi, from the client."); // this works
alert("Connection opened...");
};
ws.onmessage = function (event) {
alert("Message received..." + event.data);
};
ws.onclose = function () {
alert("Connection closed...");
};
ws.send("Hi, from the client."); // doesn't work
ws.send("Hi, from the client."); // doesn't work
}
}
</script>
</head>
<body>
<div id="sse">
Run WebSocket
</div>
</body>
</html>
You are probably experiencing a race condition where you try to perform a send command even though the socket may not have been opened yet. There's an important note on the MDN that describes this behavior:
As establishing a connection is asynchronous and prone to failure there is no guarantee that calling the send() method immediately after creating a WebSocket object will be successful.
You, essentially, are calling the send method immediately after creating a WebSocket.
If you move that logic to a function and call that function when you know the connection has been open, you might be fine. For example, try moving the code into a timeout or another function that can be manually triggered after you know the socket connection has been established:
function sendMyMessages() {
ws.send("Hi, from the client.");
ws.send("Hi, from the client.");
}
<button onclick="sendMyMessages()">Test</button>
Because onopen is an asynchronous event.
It's similar to doing this:
var value;
$.ajax({
url: '/post/data',
success: function(response) {
value = response;
}
});
alert(value);
What do we get in the alert? undefined.
The websocket works in a similar manner, you cannot send until the connection has finished opening. It opens asynchronously. Therefore, anytime you try to use send, you must ensure that the connection is already open. Right now, you are trying to synchronously use those send calls, before the connection is actually open.
This is the html file of Sanic webserver websocket demo.
<!DOCTYPE html>
<html>
<head>
<title>WebSocket demo</title>
</head>
<body>
<script>
var ws = new WebSocket('ws://' + document.domain + ':' + location.port + '/feed'),
messages = document.createElement('ul');
ws.onmessage = function (event) {
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Received: ' + event.data);
message.appendChild(content);
messages.appendChild(message);
};
document.body.appendChild(messages);
window.setInterval(function() {
data = 'bye!'
ws.send(data);
var messages = document.getElementsByTagName('ul')[0],
message = document.createElement('li'),
content = document.createTextNode('Sent: ' + data);
message.appendChild(content);
messages.appendChild(message);
}, 1000);
</script>
</body>
I want to send data via socket.io to my client via nodejs.
The data I am receiving are from pusher.
I am using an express backend and loading my server like that.
#!/usr/bin/env node
var debug = require('debug')('testApp');
var app = require('../app');
var Pusher = require('pusher-client');
app.set('port', process.env.PORT || 3000);
var server = app.listen(app.get('port'), function () {
debug('Express server listening on port ' + server.address().port);
});
/**
* return pusher data
*/
var API_KEY = 'cb65d0a7a72cd94adf1f';
var pusher = new Pusher(API_KEY, {
encrypted: true
});
/**
* Socket.io
*/
var io = require("socket.io").listen(server, {log: true});
io.sockets.on("connection", function (socket) {
// This will run when a client is connected
// This is a listener to the signal "something"
socket.on("data", function (data) {
var channel = pusher.subscribe("ticker.160");
channel.bind("message", function (data) {
console.log(data);
});
});
// This is a signal emitter called "something else"
socket.emit("something else", {hello: "Hello, you are connected"});
});
On my client I am running the following script:
index.ejs
<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' />
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/0.9.16/socket.io.min.js" />
<script src='/javascripts/socket.js'></script>
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %> Juhu!</p>
</body>
</html>
My socket.js file:
var socket = io.connect(window.location.hostname);
socket.on('data', function(data) {
var total = data.total;
//print data to console
console.log(data);
});
My problem is that nothing gets shown in the console in my webbrowser, even though the data is coming in at my nodejs application.
Any recommendation what I am doing wrong?
I appreciate your replies!
I do believe the problem is when you use: socket.emit("something else", {hello: "Hello, you are connected"});
but have this in client-side: socket.on('data', function(data) {.
When you emit, you use the channel "something else", but on the client-side you are checking on the channel "data".
So on client-side you should be having socket.on('something else', function(data){.
Hope I helped. There isn't much info I could find on sockets.io, so I do not know if there is a preexisting channel called 'data'. Do enlighten me if so :)