React JS 如何作为 WebSocket 客户端?

16

我希望创建一个基于Websocket的客户端-服务器应用程序。我已经创建了Node.js Websocket服务器,它正在等待客户端连接。现在我想创建React.js Websocket客户端。我选择使用React.js作为Websocket客户端,因为我必须不断地呈现服务器发送的文本消息。

我遇到了实现React.js作为Websocket客户端的困难。它应该如何作为Websocket客户端工作,并且它将如何像这样发送请求到Websocket服务器:

'ws://localhost:1234'

我想了解更多关于 WebSocket 客户端的内容,同时也想解决这个问题。


在您提出其他问题之前,我建议您阅读此链接:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications。 - U r s u s
好的...阅读这个页面...但我想在React JS中实现它...我的问题只是如何在React JS中实现WebSocket客户端? - ketan
5个回答

30

一个非常基本且没有太多额外开销的示例需要两个东西:

  1. 一个具有 WebSocket 连接引用的组件

  2. 连接上的事件监听器,当消息到达时更新组件的状态

演示:http://jsfiddle.net/69z2wepo/47360/
演示(2019年):http://jsfiddle.net/643atLce/

class Echo extends React.Component {
    constructor(props){
    super(props);
    this.state = { messages : [] }
  }

  componentDidMount(){
    // this is an "echo" websocket service
    this.connection = new WebSocket('wss://echo.websocket.org');
    // listen to onmessage event
    this.connection.onmessage = evt => { 
      // add the new message to state
        this.setState({
        messages : this.state.messages.concat([ evt.data ])
      })
    };

    // for testing purposes: sending to the echo service which will send it back back
    setInterval( _ =>{
        this.connection.send( Math.random() )
    }, 2000 )
  }

  render() {
    // slice(-5) gives us the five most recent messages
    return <ul>{ this.state.messages.slice(-5).map( (msg, idx) => <li key={'msg-' + idx }>{ msg }</li> )}</ul>;
  }
};

嗨,听起来不错......但是我遇到了“Bad JSFiddle配置,请fork原始的React JSFiddle”错误,我认为我的结构无效,请告诉我如何为我的React应用程序创建结构?即HTML、JS、webpack.config.js和package.json。 - ketan
1
你在哪里出现了这个错误?是在我回答中链接的演示 fiddle 上吗? - pawel
是的...我只是放置js代码并更改ws url,在html中我们使用<script>,所以出现了这个错误... - ketan
对于在上面的jsfiddle链接遇到问题的任何人。在单击链接后,您可以看到一个值为“Javascript”的HTML选择框。将此选择框切换到“React”,然后单击页面左上角的“运行”按钮。这就是我让示例正常工作的方法。 - Frito
1
@Frito更新了我的回答中的链接。这个fiddle很久以前是通过fork“React Base Fiddle”创建的(我想当时在jsfiddle中没有预定义的React配置)。谢谢! - pawel
当我打开你的fiddle时,遇到了这个错误信息InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable。为什么会出现这种情况? - yongchang

1

只需从服务器端创建rest程序并在Web页面上创建连接即可。

var connection = new WebSocket('ws://localhost/echo', ['soap', 'xmpp']);

opening the connection 
connection.onopen = function () {
  connection.send('Ping'); // 
};


connection.onerror = function (error) {
  console.log('WebSocket Error ' + error);
};

//to receive the message from server
connection.onmessage = function (e) {
  console.log('Server: ' + e.data);
};

// Sending String  
connection.send('your message');

在服务器端,您将获得会话和消息,因此您可以与N个会话进行通信。

1
这个答案仅适用于纯JavaScript。问题是如何将此答案放入ReactJS中。因此,您没有回答问题。 - septianw

1
在你的React项目文件夹中的App.js文件中添加一个WebSocket连接,并监听来自WebSocket服务器的消息。
class App extends React.Component{
  constructor(){
   super();
    this.state={
      endpoint:"ws://localhost:1234",
      messages:[]
     }
   }

  componentDidMount(){
  //initialize connection
   const ws = new WebSocket(this.state.endpoint)
    ws.onopen = () =>{
     //send any msg from Client if needed
       ws.send(JSON.stringify(temp))
  }
   //save whatever response from client
    ws.onmessage = evt =>{
     this.setState({
      message:this.state.message.concat(evt.data)
    })
  }
 }
 render(){
 return(
 <div>
 <p>{this.state.message.map(items=><li>{items}</li>)}</p>
 </div>
)}

}


0

我们中的一些人使用钩子来处理Websocket连接,但这里是我的解决方案,solution非常简单,一旦您的应用程序变得更大,您将不会混乱。


0

我在这里留下一个功能性示例(以上所有内容都是对象...)

const client = new WebSocket(ws://stream.marketpricesfun.com)
const [cottonPrice, setCottonPrice] = useState(0)

useEffect(() => {
    client.onopen = () => {
        client.send('{"topic": "subscribe", "to": "newPrices"}')
    }

    client.onmessage = (message) => {
        if (message.data) {
            const parsedData = JSON.parse(message.data)

            setCottonPrice(parsedData.cotton.price)
        }
    }

    return () => {
        client.close()
    }
}, [])

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接