I'm developing a websocket server with Node.Js v14.17.3 using "ws": "^7.4.5" package.
My server code is this:
const WebSocket = require("ws");
const url = "localhost";
const port = 8081;
const wss = new WebSocket.Server({ host: url, port });
wss.on("connection", function (ws) {
ws.on("message", function (data) {
console.log("received: %s", data);
});
function onSocketClose(code, reason) {
console.log("Closing open web socket", code, reason);
console.log("Closed web socket.");
}
ws.on("close", onSocketClose);
});
My client code is this:
window.onclose = function (event) {
console.log("Window closing.");
closeSocket("Window closed");
};
window.onunload = function (event) {
console.info("Window unloaded");
closeSocket("Window unloaded");
};
function closeSocket(reason) {
if (reason) {
console.info("Closing socket due to:", reason);
} else {
reason = "Unknown reason";
}
webSocket.onclose = function (ev) {
console.info("Websocket closed.");
};
webSocket.close(1001, reason);
}
In server on("close", ...) callback I get an empty reason, while I'm expecting the reason I've specified in client method.
Related
i'm listen websocket with sockjs in typescript and angular
my code:
webSocketOpen() {
let ws = new SockJS('http://localhost:8081/chat', null, { timeout: 6000 });
ws.onopen = () => {
console.log('a');
}
ws.onclose = () => {
console.log('b');
}
ws.onerror = () => {
console.log('c');
}
this.stompClient = Stomp.over(ws);
let that = this;
this.stompClient.connect({}, () => {
that.stompClient.subscribe("/topic/messages", (message) => {
console.log(message.body);
}, (error) => {
console.log('error');
}
);
});
}
but onclose in sockjs doesn't work when connection to server is close or connection disconnected. as well as other method onopen, onerror. please help me how to know that the websocket is disconnected or connected?
While using websocket, message that client gets is blob. Whats the best way to access its content? I have tried using FileReader but then it looked like {"user":"whatever","msg":"whatever"} and I would like to get it as {user:"whatever",msg:"whatever"}. Is it even possible?
const submitMessage = (usr, msg) => {
const message = { user: loggedInUser.username, message: msg };
ws.send(JSON.stringify(message));
setMessages([message, ...messages]);
}
useEffect(() => {
ws.onopen = () => {
console.log('WebSocket Connected');
}
ws.onmessage = (e) => {
const message = JSON.parse(e.data);
setMessages([message, ...messages]);
}
return () => {
ws.onclose = () => {
console.log('WebSocket Disconnected');
setWs(new WebSocket(URL));
}
}
}, [ws.onmessage, ws.onopen, ws.onclose, messages]);
**server**
const WebSocket = require('ws');
const wss = new WebSocket.Server({ port: 8080 });
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(data) {
wss.clients.forEach(function each(client) {
if (client !== ws && client.readyState === WebSocket.OPEN) {
client.send(data);
}
});
});
});
const { io } = require("socket.io-client");
const botSocket = io("http://localhost:1025");
botSocket.connect();
botSocket.on("connect_failed", function () {
console.log("Sorry, there seems to be an issue with the connection!");
});
botSocket.onAny((data) => {
console.log(data, "bot connect");
});
botSocket.on("connection", (data) => {
console.log(data, "bot conenct");
});
Here is my code, but when I run it, nothing is logged ever, what am I doing wrong?
I am trying to get web sockets working inside a Asp.Net Core app that is hosted under nginx inside Raspberry Pi.
My default file settings are:
location /the_socket/ {
proxy_pass http://websocket:8090/;
}
in class the websocket (using Fleck) is opened like:
var server = new WebSocketServer("ws://0.0.0.0:8090/the_socket");
server.Start(
socket =>
{
socket.OnOpen = () =>
{
};
socket.OnClose = () =>
{
};
socket.OnMessage = message =>
{
};
});
This is my calling JavaScript:
url = "ws://the_socket:8090";
$(document).ready(function () {
function Connect() {
try {
$("#lblConnectionStatus").html("Reconnecting...");
if (ws instanceof WebSocket) {
ws.close();
}
ws = new WebSocket(url);
ws.binaryType = "arraybuffer";
ws.onerror = function (e) {
$("#divInternalMessangingStatus").html("Internal Messaging Error: " + e.message);
};
ws.onclose = function () {
$("#divInternalMessangingStatus").html("Internal Messaging Closed:");
Connect();
};
ws.onopen = function () {
$("#divInternalMessangingStatus").html("Client connected");
};
ws.onmessage = function (e) {
$("#divInternalMessangingStatus").html(e.data);
};
} catch (err) {
$("#divInternalMessangingStatus").html(err);
}
}
Connect();
});
Which errors on Connection Refused...
NB
I had tried changing:
location /the_socket/ {
proxy_pass http://websocket:8090/;
}
to:
location /the_socket/ {
proxy_pass http://0.0.0.0:8090/;
}
Service Worker Message Handler:
let angularClient;
self.addEventListener('message', function(event) {
// store the client which sent the message into angularClient variable
angularClient = event.ports[0];
});
Service Worker Notification Click Handler, Which sends data to angularClient
self.addEventListener('notificationclick', function(event) {
event.notification.close();
var url = /localhost:8080|example.com|https:\/\/www.example.com/;
var newurl = "/" + event.notification.data.url;
if (event.notification.data.url) {
newurl = event.notification.data.url;
}
function endsWith(str, suffix) {
console.log(str);
console.log(suffix);
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
event.waitUntil(
clients.matchAll({
type: 'window'
})
.then(function(windowClients) {
for (var i = 0; i < windowClients.length; i++) {
var client = windowClients[i];
if (url.test(client.url) && 'focus' in client) {
if (endsWith(client.url, newurl)) {
console.log("URL matched");
console.log("sending 1");
angularClient.postMessage(sendToAngularPayload);
return client.focus();
}
return client.navigate(newurl)
.then(client => client.focus());
}
}
if (clients.openWindow) {
console.log("sending 2");
angularClient.postMessage(sendToAngularPayload); //sendToAngularPayload is defined when notification is received in firebase's messaging.setBackgroundMessageHandler.
return clients.openWindow('https://www.example.com/#/' +
event.notification.data.url);
}
})
);
},true);
AngularJs Controller with functions
Function to send message to service worker so that it stores this client
$scope.checkServiceWorker = function() {
if ('serviceWorker' in navigator) {
// ensure service worker is ready
navigator.serviceWorker.ready.then(function(reg) {
console.log("Send message");
// PING to service worker, later we will use this ping to
//identify our client.
sendMessage().then(function(event) {
console.log(event);
}).catch(function(error) {
console.log("error", error);
location.reload();
});
}).catch(function() {
console.log('SW not ready');
$scope.checkServiceWorker();
});
}
}
sendMessage function with onMessage handler
function sendMessage() {
return new Promise(function(resolve, reject) {
var messageChannel = new MessageChannel();
messageChannel.port1.onmessage = function(event) {
console.log("on message handler", event);
if (event.data.error) {
reject(event.data.error);
} else {
console.log('inside resolve', event.data);
console.log("Ping received from SW");
console.log(event);
resolve(event.data);
}
};
console.log("Sending");
navigator.serviceWorker.controller.postMessage("ping",
[messageChannel.port2]);
console.log("sent");
});
}
The problem is that onMessage Handler inside angularjs controller gets fired 90% of the times, but sometimes it does not. As I can see in the developer console, the execution stops in serviceworker.js after I print "sending 1" in the notification click handler, and does not show rest of the logs inside the controller's onMessage handler.
worker.ts
self.addEventListener("push", e => {
const data = e.data.json();
console.log("Push received");
console.log("data ", data);
self.registration.showNotification(data.title, {
body: "Notified",
})
// Broadcasting from a ServiceWorker to every client
self.clients.matchAll().then(all => all.map(client => client.postMessage(data)));
})
The listener is added on navigator.serviceWorker and not on a specific
worker
AngularJs controller:
constructor() {
navigator.serviceWorker.addEventListener('message', e => console.log(e.data));
}