使用 React-Router 维护 WebSocket 连接

Posted

技术标签:

【中文标题】使用 React-Router 维护 WebSocket 连接【英文标题】:Maintaining a WebSocket connection with React-Router 【发布时间】:2020-01-11 21:37:04 【问题描述】:

在我的 React App 中,我在主页建立了一个 websocket 连接,当用户导航到另一个路由时,连接仍然存在,但如果他们在地址栏中手动打开该路由,则不会建立连接。我只需要在每条路线上建立连接吗? React-Router 是否通过不同的路由将我的 websocket 对象保持在范围内,以便我可以做到这一点?

【问题讨论】:

【参考方案1】:

这是一个基于 react-router 的基本入门代码的工作示例。重要的是要确保 websocket 是在 App 本身中创建和打开的,而不是在任何特定的路径中。这样,无论应用程序以哪种方式打开,即在任何路由/URL 上,它都可以工作,同时仍保持路由之间的连接。

客户:

import React from "react";
import 
  BrowserRouter as Router,
  Switch,
  Route,
  Link
 from "react-router-dom";

let ws;
let buffer = [];
const sendWhenOpen = (text) => 
  if (ws.readyState == 1) 
    ws.send(text);
   else 
    buffer.push(text);
    ws.onopen = () => 
      buffer.forEach( (x) => 
        ws.send(x);
      );
    ;
  


export default function App() 
  ws = new WebSocket('ws://localhost:8080/');
  sendWhenOpen('connected!');

  return (
    <Router>
      <div>
        <nav>
          <ul>
            <li>
              <Link to="/">Home</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/users">Users</Link>
            </li>
          </ul>
        </nav>

        /* A <Switch> looks through its children <Route>s and
            renders the first one that matches the current URL. */
        <Switch>
          <Route path="/about">
            <About />
          </Route>
          <Route path="/users">
            <Users />
          </Route>
          <Route path="/">
            <Home />
          </Route>
        </Switch>
      </div>
    </Router>
  );


function Home() 
  sendWhenOpen('user opened home');
  return <h2>Home</h2>;


function About() 
  sendWhenOpen('user opened about');
  return <h2>About</h2>;


function Users() 
  sendWhenOpen('user opened users');
  return <h2>Users</h2>;

服务器:

const WebSocket = require('ws');

const wss = new WebSocket.Server( port: 8080 );

wss.on('connection', function connection(ws) 
  ws.on('message', function incoming(message) 
    console.log('received: %s', message);
  );

  ws.send('something');
);

【讨论】:

我可以将组件函数/类分离到它们自己的文件中然后导入它们吗?还是使用带有 react-router 的 websockets 意味着我不能? 是的,当然可以。这只是一个例子。如果不使用文件范围的变量,则需要将 ws 对象传递给组件。但这都是可能的,要么作为组件的道具,要么通过在共享的全局范围内定义 ws,例如 window

以上是关于使用 React-Router 维护 WebSocket 连接的主要内容,如果未能解决你的问题,请参考以下文章

react-router 不维护查询参数,调用 onEnter 两次

如何使用 React Router 维护路由之间的状态?

关于react-router最新版本的使用

[react-router] React-Router怎么获取历史对象?

如何使用 react-router 重新加载页面?

使用带有 react-router 的锚点