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!
Related
I have been advised that the solution in another SO post of mine might involve WebSocket. It just closes the connection instantly when used with my Url, but the javascript.info Url works fine. But why is that?
console.log says:
WebSocket connection to 'wss://verlager.com/hello' failed:
function sentry() {
if ("WebSocket" in window) {
console.log("WebSocket is supported by your Browser!");
// Let us open a web socket
// THIS WORKS:
let socket = new WebSocket("wss://javascript.info/article/websocket/demo/hello");
// But my server doesn't work! Why doesn't it work on my server?
var ws = new WebSocket("wss://verlager.com/hello");
ws.onopen = function() {
// Web Socket is connected, send data using send()
ws.send("Message to send");
console.log("Message is sent...");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
console.log("Message is received...");
};
ws.onclose = function() {
// websocket is closed.
console.log("Connection is closed...");
};
} else {
// The browser doesn't support WebSocket
console.log("WebSocket NOT supported by your Browser!");
}
}
sentry();
First, I've encountered an error with the exact same format, when I tried to connect to wss://localhost, which wasn't running.
Try specifying the port of your server, I'm not sure which one it assumes by default. Also make sure that your server is running secure websockets and it's dealing correctly with your path /hello.
We had created WCF web service with one method. Service is hosted on external server i.e. Windows Server 2012 and IIS 8.0.
WCF Service URL: http://184.106.9.214/WCFReportingService/Service1.svc
WCF method:
public void ProcessReport()
{
for (int i = 1; i <= 100; i++)
{
// some logic to process the report
Thread.Sleep(100);
// Get the callback channel to send messages to the client
OperationContext.Current.
GetCallbackChannel<IReportServiceCallback>().Progress(i);
}
}
We are trying to create client using HTML5 and JavaScript. Below is the logic we used to initiate the connection.
ws = new WebSocket("ws://localhost/WCFReportService/Service1.svc");
alert(ws);
ws.onopen = function () {
// Web Socket is connected, send data using send()
ws.send("Message to send");
alert("Message is sent...");
$("#spanStatus").text("connected");
};
ws.onmessage = function (evt) {
var received_msg = evt.data;
alert("Message is received...");
$("#spanStatus").text(evt.data);
};
ws.onerror = function (evt) {
$("#spanStatus").text(evt.message);
};
ws.onclose = function () {
// websocket is closed.
alert("Connection is closed...");
$("#spanStatus").text("disconnected");
};
We were not able to establish the connection to server. We are thinking that it might be something to do with client side web.config file. But we are not sure how to implement or build connection.
Can anyone help us to build client-server connection?
Thanks.
It might help someone with similar problem I had. Below are the links I used and I was able to get it working.
Introduction 2 : http://www.codeproject.com/Articles/618032/Using-WebSocket-in-NET-4-5-Part-2
Introduction 3 : http://www.codeproject.com/Articles/619343/Using-WebSocket-in-NET-4-5-Part-3
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);
Environment:
Nodejs+Socketio
Problem:
client A and client B both connect to server;
client B is offline;
client A sends a message to client B(client B still offline);
client B connect to server again;
[Problem] client B can't receive the message from A;
Server Code
var clients = {};
io.sockets.on('connection', function (socket) {
socket.on('online', function (data) {
if (!clients[data.username]) {
clients[data.username] = socket;
}
io.sockets.emit('message', data.user + 'online now');
});
socket.on('say', function (data) {
if (data.to == 'all') {
io.sockets.emit('message', data.message);
} else { //to specific client
clients[data.to].emit('message', data.message);
}
});
});
Description
client B connected to server at one place first.During the period of client B's offline, client A sent messages to client B. Then client B connect to server at another place again, and client B needs to receive those message from client A. How to make it work?
The amount of code I would have to write would be fairly large to create a solution if I consider which db and it's config, and client. You basically have to persist your messages in a database. As messages come in you would have to write to your conversation object (or whatever is representing the chat messages between clients).
socket.on('say', function (data) {
// pseudo code to save conversation
// var conversation = db.getConversation();
// conversation.addMessage(data.message);
// conversation.save();
if (data.to == 'all') {
io.sockets.emit('message', data.message);
} else { //to specific client
clients[data.to].emit('message', data.message);
}
});
Then you would have to get all messages from the database when a client joins.
socket.on('online', function (data) {
if (!clients[data.username]) {
clients[data.username] = socket;
}
// pseudo code to get messages and display to user on first load
// var conversation = db.getConversation();
// var messages = conversation.getLast10Messages();
// messages.forEach(function(message) {
// clients[data.username].emit('message', message);
// });
io.sockets.emit('message', data.user + 'online now');
});
use message queue like RabbitMQ. whenever a message comes from socket write to receiver's queue and when the receiver joins he will pick it from the queue.
You can specify a unique id as username to every user , save it at the server side, or use username, you also have client id(socket id), then save them in an object, now for every user you have an object that contains (username or unique id ) and socket id, now its easy to save messages when user is offline and then send it to user.
Before emitting every event, you can search for socket id in the connected sockets object of socket.if socket id exists, you can emit, else , you still have username, and you can save messages in database by username.
Remember that, you must send receiver object info(username or unique id , and socket id) in every emitting from the client
I'm trying to develop a video-chat application using webRTC and WebSockets for signaling.
My problem is that I don't know exactly what is the process of creating RTCPeerConnection and connect both peers(2 browsers) through webSocket(Locally at least).
I know how to communicate clients though WebSockets, but not with the RTCPeerConnection API, you know any tutorial step-by-step explaining the process?(Offer SDP, answers, ICE, ...) and, on the other hand, how looks the server code to managing these clients through RTCPeerConnection?
Here is my Node.js code for the server
"use strict";
// Optional. You will see this name in eg. 'ps' or 'top' command
process.title = 'node-webrtc';
// Port where we'll run the websocket server
var webSocketsServerPort = 1337;
// websocket and http servers
var webSocketServer = require('websocket').server;
var http = require('http');
/* ---------------------------------
GLOBAL VARIABLES
----------------------------------*/
// latest 100 messages
//var history = [ ];
// list of currently connected clients (users)
var clients = [ ];
/* ---------------------------------
HTTP SERVER
----------------------------------*/
var server = http.createServer(function(request, response) {
// Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
});
/* ---------------------------------
WEBSOCKET SERVER
----------------------------------*/
var wsServer = new webSocketServer({
// WebSocket server is tied to a HTTP server. WebSocket request is just
// an enhanced HTTP request. For more info http://tools.ietf.org/html/rfc6455#page-6
httpServer: server
});
// This callback function is called every time someone
// tries to connect to the WebSocket server
wsServer.on('request', function(request) {
console.log((new Date()) + ' Connection from origin ' + request.origin + '.');
// accept connection - you should check 'request.origin' to make sure that
// client is connecting from your website
// (http://en.wikipedia.org/wiki/Same_origin_policy)
var connection = request.accept(null, request.origin);
// we need to know client index to remove them on 'close' event
var index = clients.push(connection) - 1;
console.log((new Date()) + ' Connection accepted.');
// user sent some message
connection.on('message', function(message) {
for (var i=0; i < clients.length; i++) {
clients[i].sendUTF(message);
}
});
// user disconnected
connection.on('close', function(conn) {
console.log((new Date()) + " Peer " + conn.remoteAddress + " disconnected.");
// remove user from the list of connected clients
clients.splice(index, 1);
});
});
You might want to have a look at the codelab I did for Google I/O: bitbucket.org/webrtc/codelab.
Step 5 shows how to set up a signaling server using socket.io, and Step 6 puts this together with RTCPeerConnection to make a simple video chat app.
You might also want to have a look at easyRTC (full stack) and Signalmaster (signaling server created for SimpleWebRTC).
The 'canonical' WebRTC video chat example at apprtc.appspot.com uses XHR and the Google App Engine Channel API for signaling.
Have you looked at or come across WebRTC.io? It is an opensource GitHub project that utilizes Node.js and websockets to do the exact thing you are talking about. I, not being much of a javascript person, was able to figure out what it was doing within a week. It isn't a step by step instruction, but anyone with javascript experience would be able to figure out the function call order.
There are two bits to the code: the server side and the client side. The server side is run with Node.js, and serves up the client side code to the browser. If I remember correctly, since the two projects are separate, if you want to combine them you will have to copy the webrtcio.js file from the client side and paste it into the server side folder. Although, I think if you clone the github repository right, you might not have to worry about that.