简体   繁体   English

如何检测从 Websocket 服务器发送的消息

[英]How to detect which message was sent from the Websocket server

I have a small web application listening for incoming messages from a Websocket server.我有一个小型 Web 应用程序,用于侦听来自 Websocket 服务器的传入消息。 I receive them like so我像这样接收它们

 const webSocket = new WebSocket("wss://echo.websocket.org"); webSocket.onopen = event => webSocket.send("test"); webSocket.onmessage = event => console.log(event.data);

but the sending server is more complex.但发送服务器更复杂。 There are multiple types of messages that could come eg "UserConnected", "TaskDeleted", "ChannelMoved"可能会出现多种类型的消息,例如“UserConnected”、“TaskDeleted”、“ChannelMoved”

How to detect which type of message was sent?如何检测发送的消息类型? For now I modified the code to现在我将代码修改为

 const webSocket = new WebSocket("wss://echo.websocket.org"); webSocket.onopen = event => { const objectToSend = JSON.stringify({ message: "test-message", data: "test" }); webSocket.send(objectToSend); }; webSocket.onmessage = event => { const objectToRead = JSON.parse(event.data); if (objectToRead.message === "test-message") { console.log(objectToRead.data); } };

So do I have to send an object from the server containing the "method name" / "message type" eg "TaskDeleted" to identify the correct method to execute at the client?那么我是否必须从服务器发送一个包含“方法名称”/“消息类型”的对象,例如“TaskDeleted”,以确定在客户端执行的正确方法? That would result in a big switch case statement, no?那会导致一个很大的 switch case 语句,不是吗?

Are there any better ways?有没有更好的方法?

You can avoid the big switch-case statement by mapping the methods directly:您可以通过直接映射方法来避免大的 switch-case 语句:

// List of white-listed methods to avoid any funny business
let allowedMethods = ["test", "taskDeleted"];

function methodHandlers(){
  this.test = function(data)
  {
     console.log('test was called', data);
  }

  this.taskDeleted = function(data)
  {
     console.log('taskDeleted was called', data);
  }
}


webSocket.onmessage = event => {
  const objectToRead = JSON.parse(event.data);
  let methodName = objectToRead.message;
  if (allowerMethods.indexOf(methodName)>=0)
  {
     let handler = new methodHandlers();
     handler[methodName](data);
  }
  else
  {
     console.error("Method not allowed: ", methodName)
  }
 };

Based on Eriks Klotins answer I want to provide a solution I'm currently working with.基于 Eriks Klotins 的回答,我想提供一个我目前正在使用的解决方案。 But it's necessary to define a message format.但是有必要定义一个消息格式。 I thought about this format我想过这种格式

{
    "event": "event name goes here",
    "data": {
        "arg1": "first argument"
    }
}

Based on this I modified the code to基于此,我将代码修改为

 const webSocket = new WebSocket("wss://echo.websocket.org"); webSocket.onopen = event => { const objectToSend = JSON.stringify({ event: "test", data: { argOne: "argument 1" } }); webSocket.send(objectToSend); }; webSocket.onmessage = event => { const objectToRead = JSON.parse(event.data); const eventMethods = events(); const eventMethod = eventMethods[objectToRead.event]; eventMethod(objectToRead.data); }; function events(){ return { test: function({ argOne }) { console.log(argOne); } }; }

As you have requested in one of your comments to have a fluent interface for the websockets like socket.io.正如您在其中一条评论中所要求的那样,为 socket.io 等 websocket 提供流畅的界面。

You can make it fluent by using a simple PubSub (Publish Subscribe) design pattern so you can subscribe to specific message types.您可以使用简单的 PubSub(发布订阅)设计模式使其流畅,以便您可以订阅特定的消息类型。 Node offers the EventEmitter class so you can inherit the on and emit events, however, in this example is a quick mockup using a similar API. Node 提供了EventEmitter类,因此您可以继承onemit事件,但是,在此示例中是使用类似 API 的快速模型。

In a production environment I would suggest using the native EventEmitter in a node.js environment, and a browser compatible npm package in the front end.在生产环境中,我建议在 node.js 环境中使用本机 EventEmitter,并在前端使用浏览器兼容的 npm 包。

Check the comments for a description of each piece.检查评论以获取每件作品的描述。

The subscribers are saved in a simple object with a Set of callbacks, you can add unsubscribe if you need it.订阅者保存在一个带有一组回调的简单对象中,如果需要,您可以添加取消订阅。

note: if you are using node.js you can just extend EventEmitter注意:如果你使用 node.js 你可以扩展 EventEmitter

 // This uses a similar API to node's EventEmitter, you could get it from a node or a number of browser compatible npm packages. class EventEmitter { // { [event: string]: Set<(data: any) => void> } __subscribers = {} // subscribe to specific message types on(type, cb) { if (!this.__subscribers[type]) { this.__subscribers[type] = new Set } this.__subscribers[type].add(cb) } // emit a subscribed callback emit(type, data) { if (typeof this.__subscribers[type] !== 'undefined') { const callbacks = [...this.__subscribers[type]] callbacks.forEach(cb => cb(data)) } } } class SocketYO extends EventEmitter { constructor({ host }) { super() // initialize the socket this.webSocket = new WebSocket(host); this.webSocket.onopen = () => { this.connected = true this.emit('connect', this) } this.webSocket.onerror = console.error.bind(console, 'SockyError') this.webSocket.onmessage = this.__onmessage } // send a json message to the socket send(type, data) { this.webSocket.send(JSON.stringify({ type, data })) } on(type, cb) { // if the socket is already connected immediately call the callback if (type === 'connect' && this.connected) { return cb(this) } // proxy EventEmitters `on` method return super.on(type, cb) } // catch any message from the socket and call the appropriate callback __onmessage = e => { const { type, data } = JSON.parse(e.data) this.emit(type, data) } } // create your SocketYO instance const socket = new SocketYO({ host: 'wss://echo.websocket.org' }) socket.on('connect', (socket) => { // you can only send messages once the socket has been connected socket.send('myEvent', { message: 'hello' }) }) // you can subscribe without the socket being connected socket.on('myEvent', (data) => { console.log('myEvent', data) })

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何指定我从nodejs服务器发送到哪个websocket端点 - how can specify which websocket endpoint I sent to from nodejs server 检测哪个 iframe 发送了 post 消息 - detect which iframe sent post message 是否使用WebSocket或服务器发送事件从服务器发送通知以实时检索社交网络状态? - Whether to use WebSocket or Server Sent Event for sending notifications from server which retrieves social network presence in realtime? 给定节点上的服务器。 js,如何监听从WebSocket发送到服务器的呼叫? - Given a server on Node. js, How do I listen to the calls sent to the server from WebSocket? Javascript Websocket 检查是否没有从服务器收到消息 - Javascript Websocket check if no message received from server 如何设置Websocket与客户端和服务器发送事件服务器通信? - How to set Websocket to communicate with a client and a server-sent-events server? 如何检测来自服务器用户的消息中的图像并回复? - How detect image in a message from the server users and reply? 如何在桌面上调试 WebSocket/Server Sent Events 重新连接? - How to debug WebSocket / Server Sent Events reconnections on desktop? websocket服务器未收到消息 - websocket server not receiving message 如何提取服务器发送的错误信息? - How to extract the error message sent by the server?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM