WebSocket not showing js alert - javascript

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.

Related

How to make XMLHttpRequest reuse a TCP connection?

I have Apache running on Windows 7 Pro. I installed Apache using XAMPP bundle.
I need to call an API once every second. To do that, I created a SharedWorker who calls the API every second using XMLHttpRequest
However, I am running into an issue where the web server Apache hits it's max TCP connection allowed. Of course I can increase the allowed TCP connections on the server, but that does not solve my problem it only patches it until the server gets busy and overloaded.
After troubleshooting the TCP problem, it become clear to me that the XMLHttpRequest is not reusing an existing TCP connection. It opens a new TCP connection with every request/every second. I expect to have 1 TCP connection to be utilized to handle my XMLHttpRequest connection.
While I was the only user is connection to the website on the server, I launched TCPView on the web server to watch the tcp connections. I started out with 30 TCP connection with a state of TIME_WAIT. Every second later, one more connection was created until it reached about 122-130 and then it stopped. Now the server seems to be recycling the connections every 60 seconds, but still generating a new TCP connection for every XMLHttpRequest every second.
I also understand that each time a page is loaded the client/browser could create multiple TCP connection for various of reasons. But, I am expecting to have 1 TCP connection to handle my XMLHttpRequest and resuse that connection over and over.
I know some may suggest using WebSockets or Server-Sent-Events, but in my case I can't. I must keep my ShardWorker implementation.
Question
What can I do to make the XMLHttpRequest reuse of an open TCP connection?
Below is my ShardWorker implementation i.e. worker.js
var clients = new Array();
var xhr = null;
//runs only when a new connection starts
onconnect = function(event) {
var port = event.ports[0];
clients.push(port);
port.start();
//implement a channel for a communication between the connecter and the SharedWorker
port.addEventListener("message",
function(event) {
replyToClientMessage(event, port);
} , false
);
}
//reply to any message sent to the SharedWorker with the same message but add the phrase "SharedWorker Said: " to it
replyToClientMessage = function (event, port) {
port.postMessage("Worker Replied With: " + event.data);
}
//check all open clients and post a message to each
function notifyAllPorts(msg){
var len = clients.length;
var port;
for(i = 0; i < len; i++) {
port = clients[i];
port.postMessage(msg);
}
}
function checkQueue(cb) {
//create a new XMLHttpRequest only once
if (xhr == null) {
xhr = new XMLHttpRequest();
xhr.addEventListener("loadend", cb);
xhr.addEventListener("load", handlerMessageReceived);
}
xhr.open('GET', '/add-ons/icws/push.php', true);
xhr.send();
}
//handler a sucessfull request
function handlerMessageReceived()
{
var queue = JSON.parse(this.responseText);
notifyAllPorts(queue);
}
var promise = Promise.resolve(true);
setInterval(function () {
promise = promise.then(function () {
return new Promise(function (resolve) {
checkQueue(resolve);
});
});
}, 1000);
Here is how I put Sharedworker to work
//establish connection to the shared worker
var worker = new SharedWorker("/add-ons/icws/js/worker.js" );
//listen for a message send from the worker
worker.port.addEventListener("message",
function(event) {
console.log(event.data);
processServerData(event.data);
}
, false
);
worker.onerror = function(event){
console.log(event);
};
//start the connection to the shared worker
worker.port.start();

WCF Full Duplex Application with Websocket Client

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

How to properly close a Node.js TCP server?

I couldn't find a clear answer on Google or SO.
I know a net.Server instance has a close method that doesn't allow any more clients in. But it doesn't disconnect clients already connected. How can I achieve that?
I know how this can be done with Http, I guess I'm asking if it's the same with Tcp or if it's different.
With Http, I'd do something like this:
var http = require("http");
var clients = [];
var server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/plain"});
response.end("You sent a request.");
});
server.on("connection", function(socket) {
socket.write("You connected.");
clients.push(socket);
});
// .. later when I want to close
server.close();
clients.forEach(function(client) {
client.destroy();
});
Is it the same for Tcp? Or should I do anything differently?
Since no answer was provided, here is an example of how to open and (hard) close a server in node.js:
Create the server:
var net = require('net');
var clients = [];
var server = net.createServer();
server.on('connection', function (socket) {
clients.push(socket);
console.log('client connect, count: ', clients.length);
socket.on('close', function () {
clients.splice(clients.indexOf(socket), 1);
});
});
server.listen(8194);
Close the server:
// destroy all clients (this will emit the 'close' event above)
for (var i in clients) {
clients[i].destroy();
}
server.close(function () {
console.log('server closed.');
server.unref();
});
Update: Since using the above code, I've ran into an issue that close will leave the port open (TIME_WAIT in Windows). Since I'm intentionally closing the connection, I'm using unref as it appears to fully close the tcp server, though I'm not 100% if this is the correct way of closing the connection.
I am using NodeJS v16.13.2 ... When the process containing the server code exits, all clients connection are closed/destroyed by default.
I came here to find out how I could listen for a server.("exit", myTaskCallback), since I wanted to delete some files while exiting the server. But the answer I have found is that such event does not exists. I had to listen to process.on('exit', myTaskCallback) to do the job.
sock.end(); //to correctly send the end of the connection in both sides
sock.on("close", fn) //add event listeners to destory all related sockets and clients
sock.on("close", () => { sock.destroy() }) //to destroy your side socket wrapper
Example:
const closeConn = async (sock, cb) => {
sock.ev.on("close", async ()=>{
await sock?.destroy();
if (typeof cb === "function") cb();
});
await sock?.end();
}
closeConn(sock, openSock);
You can check more here

Listening websocket in MVC

I'm using MVC 4. I have a js code that needs to communicate with the server with the help of Websockets. I'm using Fleck at the server. I'm creating the socket server in Application_Start event. But when I try the connection from browser console, I get errors like Connection refused.
Here is my global.asax code.
protected void Application_Start()
{
IPAddress ip = null;
if (GetResolvedConnecionIPAddress(out ip)) // Get host ip
{
string Domain = "wss" + System.Uri.SchemeDelimiter + ip + ":" + "8092";
FleckLog.Level = Fleck.LogLevel.Debug;
try
{
if (GetResolvedConnecionIPAddress(out ip))
{
var server = new WebSocketServer(Domain);
server.Start(socket =>
{
LogWriter.Logger.Info("WS: Inside socket server");
socket.OnOpen = () =>
{
LogWriter.Logger.Info("WS: OnOpen socket");
};
socket.OnClose = () =>
{
LogWriter.Logger.Info("WS: OnClose socket");
};
socket.OnMessage = message =>
{
LogWriter.Logger.Info("WS: OnMsg socket");
};
});
}
}
catch (Exception e)
{
throw;
}
}
}
It looks like as soon as the Application_Start method ends, that WebSocketServer is going to get out of scope and eventually garbage collected.
You could, set that object as member in the Global class, and dispose it on the Application_End event for example.
UPDATE:
You are also using the wss schema but not providing any certificate configuration. Please note that IIS and Fleck are two different things, that runs in different ports, and not because you create Fleck into the ASP.NET app means that Fleck is going to infer the SSL/TLS configuration or any configuration at all. Try to set the schema to ws instead and open the page without HTTPS and see if it works.

HTML5 WebSocket: Client's messages are buffered in Google Chrome 22

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!

Categories

Resources