I am trying to use the App Engine Channel API to avoid polling for updates in my client. The problem is that I see an continuous stream of XHR packets sent in the Chrome console after starting a socket. They all say:
XHR finished loading: GET "http://localhost:8080/_ah/channel/devcommand=poll&channel=xxxOMITTEDxxx-channel-yyyOMITTEDyyy-zzzOMITTEDzzz-1&client=1". jsapi:5406goog.net.XhrIo.send jsapi:5406goog.net.XhrIo.send jsapi:5352goog.appengine.DevSocket.poll_
I would not expect any XHR messages until the server tries to send a message. I am using the Python dev_appserver.
Maybe I am doing something wrong in my Javascript. I am successfully requesting a token from the server. When my client receives the token, I start the socket like this:
function listen_to_channel(msg) {
console.log('--- server response to channel request: ' + JSON.stringify(msg));
// open a channel socket
var channel = new goog.appengine.Channel(msg.token);
var socket = channel.open();
socket.onopen = function(){ console.log('socket.onopen')};
socket.onmessage = function(msg){ console.log('socket.onmessage: ' + msg.data)};
socket.onerror = function(err){ console.log('socket.onerror: ' + err.description + ', ' + err.code)};
socket.onclose = function(){ console.log('socket.onclose')};
}
I run that code from jQuery, like so:
$(document).ready(function() {
$.get('/admin/channel', {clientID:1}, listen_to_channel, 'json')
});
I link the dependencies like so:
<head>
<script type="text/javascript" src="/_ah/channel/jsapi"></script>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="javascript/admin.js"></script>
</head>
The example code is clear that the socket should be created within the tag of the HTML DOM. Is this the cause of my problem? If so, what does creating the socket within the tag do differently?
Polling is how the channel-API is simulated in the SDK, so what you're seeing is expected.
Related
I am developing an application which will show data on browser received from server using Ver.x. So, I have the following modules:
server.java:
NetServer server = vertxx.createNetServer();
server.connectHandler(new Handler<NetSocket>() {
#Override
public void handle(final NetSocket sock) {
System.out.println("A client has connected");
while (true) {
//Sending Message to Client after each five seconds
Thread.sleep(5000);
socket.write("HELLO Server: I am Client: " + i);
}
}
});
client.js:
var client = vertx.createNetClient();
client.connect(1234, 'localhost', function(err, sock) {
sock.dataHandler(function(buffer) {
//Here I received data sent from server. Now, I want to show this data on browser.
});
});
So, I want to show data on browser received on client from server. What can be possibilities for this? How I can show this data on browser gradually as received on client from server? Will I have to use some third component like vertex event bus? I need to append it in some HTML file to show data. Thanks
why you don't use websockets..also you can check the event bus bridge...which allows you send and receive data from a event bus from your browser (basically you use websocket like other eventBus)
http://vertx.io/core_manual_java.html#sockjs-eventbus-bridge
<script src="http://cdn.sockjs.org/sockjs-0.3.4.min.js"></script>
<script src='vertxbus.js'></script>
<script>
var eb = new vertx.EventBus('http://localhost:8080/eventbus');
eb.onopen = function() {
eb.registerHandler('some-address', function(message) {
console.log('received a message: ' + JSON.stringify(message);
});
eb.send('some-address', {name: 'tim', age: 587}); //--------2)
}
</script>
here you have a bus in your server named 'some-addres' then you can send data directly from your browser 2)
and you can register a eventbus and send it data from your server...
this is pretty clear, only remember configure your bus correctly allowing or not which bus are visibles from the browser..
vertx.createSockJSServer(server).bridge(config, noPermitted, noPermitted);
i am trying to get a chat program to work using socket.io but it doesnt seem to work properly.
i am using a Node.js server and it seems to be running properly. i think this may have something to do with emitting to rooms.
the code i have on the client browser is:
<script>
var socket = io("https://localhost:3000/userChat");
socket.on('connect', function(){
socket.emit('initialiseConnection', "user1");
});
socket.on('messageIn', function(msg){
console.log(msg);
$('#messages').append($('<li>').text(msg.message));
});
</script>
so when the page loads, socket.io it connects to the server and emits the "initialiseConnection" event on the server with "user1". which is a new room specifically for that user.
on the server, the code i have handling "initialiseConnection" is:
socket.on("initialiseConnection", function(username){
socket.join(username);
console.log(username + " has joined.");
Message.find({recipient:username}, function (err, message){
console.log("messages for "+username+": "+message.length);
for (var x = 0; x < message.length; x++){
console.log(username+"'s message "+x);
console.log(message[x]);
socket.to(username).emit("messageIn", {"message":message[x]});
}
});
});
this code as you can see, creates and joins a room with the same name as the username. the looks in the database for any messages, and tries to emit those messages to the user. i log the message. there is definately a message and the username in the "socket.to()" method is also correctly shown in the logs. but the "socket.on('messageIn')" on the client browser doesnt seem to be picking up the event.
i have also tried putting:
setTimeout(function() {
socket.to(username).emit("messageIn", {"message":"test message"});
}, 5000);
immediately after the socket.join(), in case this was related to some backbround processing that needed to complete
can anyone see where i may have gone wrong on this?
Thanks.
--EDIT 1--------------------------------------
var https = require('https');
var express = require('express');
var app = express();
var server = https.createServer(https_options, app).listen(3000);
var io = require('socket.io')(server);
var userChat = io.of("/userChat");
userChat.on('connection', function(socket){
console.log('a user connected');
socket.on("initialiseConnection", function(username){
...
});
socket.on('disconnect', function(){
socket.leave(socket.room);
});
});
You need to change this:
socket.to(username).emit("messageIn", {"message":message[x]});
to this:
socket.emit("messageIn", {"message":message[x]});
A socket is the endpoint. When sending, you just send directly to the socket. You don't send to a user in a room? You just send to a socket. Since you already have the socket in your socket variable, that's what you send to.
okay so i know how to show my socketid in my client code.
heres what i use for sessionid.
<script src="/js/socket.io.js"></script>
<script type="text/javascript">
var socket = io.connect('https://example-c9.c9.io/');
socket.emit('Start', 'tobi', function (data) {
var sessionid = socket.socket.sessionid;
console.log(data + " " + sessionid); // data will be 'woot'
});
</script>
Problem is i want to see what url is used to connect so i can use it later in another page
of my frontend
i am looking to get a url that looks like so
https://example.c9.c9.io/socket.io/1/?t=1396888886995
is there any way i can do this with socketio
I don't understand what are you trying to do, but I have two suggestions.
1.- You can send your current path to socket.io with an event.
2.- To know the url or path where the user gets connected you can do this:
io.sockets.on('connection', function(socket) {
console.log('new connection', socket.handshake);
});
I am writing a very simple chat application based on the HTML5 WebSocket technology where the server (implemented using node.js WS) keeps track of all the connected users and broadcasts each received message. The client on the other hand, connects to the server and according to user's actions, sends messages to the server.
The problem that I am observing is that unless the server sends a message to the client after opening the connection, all messages sent from the client running on Google Chrome get buffered until several messages have been sent. Once the buffer is full, all messages are sent at once. This creates a very unresponsive chat experience for the end user.
The fix that I found was to add single ws.send("Hello Client:" + clientId); after opening the connection on the server side, but I am not sure why this is necessary? Below you can find snippet from my client and server components, but the entire source code is available at ChatMate git project.
Server Code:
wsServer.on('connection', function (ws) {
var clientId = nextClientId += 1;
clients[clientId] = ws;
log("Accepted connection from client " + clientId + ".");
//The fix: If you emit this initial message from the server, then
//all of client's messages will be cached.
ws.send("Hello Client: " + clientId);
ws.on('message', function (message) {
log("Received message: " + message);
var id;
for (id in clients ) {
if (clients.hasOwnProperty(id)) {
if (parseInt(id, 10) !== clientId) {
clients[id].send(message);
}
}
}
});
});
Client Code:
function WebSocketTest() {
"use strict";
ws = new WebSocket("ws://DOMAIN:8080/");
ws.onopen = function () {
console.log("Connection is open.");
//This message will not be sent if the server does not send
//a message first.
ws.send("Client Message.");
};
ws.onmessage = function (e) {
console.log("Message is received: " + e.data);
};
}
Thanks!
I'm trying to put together a simple "Hello World" style application with SignalR. The slightly complicating factor is that the SignalR hubs need to be self-hosted, not in IIS/ASP.NET. I've got the server-side working, so far as I can tell, and it's available on port 8080, but I'm having trouble wiring up the client. The problem I'm bumping up against at the moment is that the SignalR client seems to be ignoring the port on the URL that I specify.
Specifically, I've got this code here:
<head runat="server">
<script type="text/javascript" src="/Scripts/jquery-1.8.2.min.js"></script>
<script type="text/javascript" src="/Scripts/json2.min.js"></script>
<script type="text/javascript" src="/Scripts/jquery.signalR-0.5.3.js"></script>
<script type="text/javascript" src="http://<%=Request.Url.Host %>:8080/signalr/hubs"></script>
<title>SignalR Test</title>
</head>
<body>
<script type="text/javascript">
$(function () {
// Wire up the client to the SignalR server on the same host
// as the source of this page, but on port 8080.
$.connection.url = "http://<%=Request.Url.Host %>:8080/signalr";
var roomHub = $.connection.roomHub;
$('#echoButton').click(function () {
roomHub.echo($('#echoButton').val())
.error(function (err) {
alert(err);
});
});
$.connection.hub.start({ transport: 'auto', xdomain: true })
.done(function () {
console.log('Connected.');
})
.fail(function (e) {
console.log('Unable to connect:' + e);
});
});
</script>
The :8080/signalr/hubs script loads successfully, and it looks good, i.e., it has the definition for the roomHub in it, so I know that the server is up and running.
However, when $.connection.hub.start() runs, it seems like it should try to open up a connection for a URL something like http://app.dev.alanta.com:8080/signalr/signalr/negotiate?=1353072553935. Instead, Firebug tells me that it's ignoring the 8080 portion, and is instead trying to negotiate a connection with the URL http://app.dev.alanta.com/signalr/signalr/negotiate?=1353072553935. And of course, that doesn't work - there's no SignalR service listening on port 80, just the regular web server - so it fails with the message, "Unable to connect:SignalR: Error during negotiation request".
I should also note that in the jquery.signalR-0.5.3.js file, the bit of code that parses out the connection does indeed seem to ignore the port:
// Resolve the full url
parser.href = connection.url;
if (!parser.protocol || parser.protocol === ":") {
connection.protocol = window.document.location.protocol;
connection.host = window.document.location.host;
connection.baseUrl = connection.protocol + "//" + connection.host;
}
else {
connection.protocol = parser.protocol;
connection.host = parser.host;
connection.baseUrl = parser.protocol + "//" + parser.host;
}
// Set the websocket protocol
connection.wsProtocol = connection.protocol === "https:" ? "wss://" : "ws://";
Is this a bug? Or have I misunderstood something?
Well, I could swear that I'd tried this and it didn't work, but as I was troubleshooting it some more, I changed the URL assignment from this:
$.connection.url = "http://<%=Request.Url.Host %>:8080/signalr";
To this:
$.connection.hub.url = "http://<%=Request.Url.Host %>:8080/signalr";
And to be sure, this is how it's documented here. I thought that I'd seen it documented the first way somewhere, but I can't find it now. Oh well. Chalk this one up to my not paying enough attention.