Replies: 2 comments 3 replies
-
Hey, You'll require a class WebSocketClient {
callbackMap = new Map();
connect() {
this.socket = new WebSocket("ws://localhost:8080");
this.addEventListeners();
}
addEventListeners() {
this.socket.onopen = () => {
console.log('Socket is open');
};
this.socket.onmessage = (event) => {
console.log('Socket message: ', event.data);
const [context, ...message] = event.data.split(' ');
if (this.callbackMap.has(message.messageId)) {
const { resolve, reject, cb } = this.callbackMap.get(message.messageId);
if (message.error === 'error') {
reject(message);
}
else {
resolve(cb(message));
}
}
else {
// route the message to the correct context
}
};
this.socket.onclose = (event) => {
console.log('Socket is closed', event);
};
this.socket.onerror = (event) => {
console.log('Socket error: ', event);
};
}
async emit(event, data, cb) {
data.messageId = Math.random().toString(36).substr(2, 9); // generate a random id
this.socket.send(`${event} ${JSON.stringify(data)}`);
return new Promise((resolve, reject) => {
this.callbackMap.set(data.messageId, { resolve, reject, cb });
});
}
} Sample code on your BE would look like this class UWebSockets {
app;
constructor() {
this.app = App();
this.app
.ws('/ws', {
open: (ws) => {
console.log('open', ws);
},
message: (ws, message) => {
const messageString = txtDecoder.decode(message);
const [context, ...messageObj] = messageString.split(' '); // FE sends data as string with space in between
const recMessage = JSON.parse(messageObj.join(' '));
console.log(recMessage.messageId); // id recieved from FE
// do some work
const response = {
messageId: recMessage.messageId, // make sure we attach the messageId so FE can call the appropriate callback
data: 'some data',
}
ws.send(`${context} ${JSON.stringify(response)}`); // send back to FE
},
});
}
} Notice that we're sending messageId from BE while emitting so FE can call the appropriate callback stored in the client-side map. Side note: Looks like you're using mediasoup, amazing library :) |
Beta Was this translation helpful? Give feedback.
1 reply
-
// example
const response = await ws.send('echo', 123); // response = 123
// client
class WebSocketClient {
constructor(url) {
this.url = url;
this.firstConnect = this.connect();
}
connect() {
return new Promise((resolve, reject) => {
this.ws = new WebSocket(this.url);
this.ws.onopen = e => { console.log('ws-open', new Date()); resolve(); };
this.ws.onerror = e => { console.log('ws-error', new Date()); reject('error'); };
this.ws.onclose = e => {
console.log(`ws-close code:${e.code} clean:${e.wasClean} reason:${e.reason || ''}`, new Date());
if (!e.wasClean) setTimeout(() => this.connect(), 2000);
};
this.ws.onmessage = e => {
const message = JSON.parse(e.data);
const sent = this.sentMessages.get(message.id);
if (sent) {
message.error ? sent.reject(message.error) : sent.resolve(message.data);
this.sentMessages.delete(message.id);
}
};
});
}
send(type, data) {
return new Promise((resolve, reject) => {
if (this.ws.readyState != 1) throw 'disconnected';
const id = ++this.messageID;
const request = data ? { id, type, data } : { id, type };
this.ws.send(JSON.stringify(request));
this.sentMessages.set(id, { resolve, reject });
});
}
messageID = 0;
sentMessages = new Map();
}
const ws = new WebSocketClient(url);
ws.firstConnect.then(async () => {
const response = await ws.send('echo', 123);
console.log(response); // 123
});
// server
app.ws('/', {
message: (ws, message) => {
try { var request = JSON.parse(Buffer.from(message).toString()); }
catch(e) { return console.log('Json Parse Error', e); }
switch (request.type) {
case 'echo': return ws.send(JSON.stringify({ id: request.id, data: request.data }));
}
}
}); |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hi:
I have a code template provided by the framework, as follows:
transport.on("produce", async (parameters, callback, errback) =>
{
// Signal parameters to the server side transport and retrieve the id of
// the server side new producer.
try
{
const data = await mySignaling.send(
"transport-produce",
{
transportId : transport.id,
kind : parameters.kind,
rtpParameters : parameters.rtpParameters,
appData : parameters.appData
});
}
catch (error)
{
// Tell the transport that something was wrong.
errback(error);
}
});
among them, await mySignaling.send can be implemented using socket. io emit function. I tried to use websocket. onmessage for implementation, but can cause WebSocket is not open: readyState 0 (CONNECTING) error , and I don't know how to solve it. Or some other method to solve the problem of obtaining data for await mySignaling.send
Thank you
Beta Was this translation helpful? Give feedback.
All reactions