react搭建websocket通信架构

前言

随着跨端技术的发展,前端开发职能不再局限于浏览器,而是具备了很多客户端开发的能力,比如桌面应用框架Electorn,移动App框架React native.

一般而言,前端同学对http协议非常熟悉,在平时的工作中使用http与后端通信居多.但在原生客户端领域,比如Java语言开发的安卓应用,与后端通信的方式大多采用socket.

众所周知,http连接是一种短连接,即客户端向服务器端发送一次请求,服务器端响应后连接即会断掉.而socket连接是一种长连接,理论上客户端和服务器端一旦建立起连接将不会主动断掉.

前端领域存在一个和socket连接功能相似的通信协议,即WebSocket.WebSocket创建了一种持久性的连接,后端不仅能正常处理客户端发送的消息,还能主动向客户端推送消息.

后端主动推送消息的能力在一些特殊的场景中太重要了,比如App接受到的信息通知,即时通讯接受的好友信息,另外面板上实时展现波动的金融数据.

不管是桌面应用框架Electron,还是App开发框架React native,它们都拥有基于原生平台封装的WebSocket.比起浏览器端开放的WebSocket,原生平台提供的支持要稳定很多.

因此在使用前端技术开发客户端应用时,完全可以使用WebSocket协议作为前后端通信的主要方式,不再需要往项目中引入http,因为http拥有的能力WebSocket同样也能找到替代方案.

本文接下来将详细介绍用react hook开发一款客户端应用时,如何在项目中搭建有效的通信机制,让WebSocketredux有机结合,在不影响前端习惯的编程风格下,建立起客户端与服务器的全双工通信.

实现

数据格式

前后端约定连接建立后,使用WebSocket协议通信的数据格式(参考如下).

{
   request_id,
   command,
   data,  
}
  • request_id是一段随机生成的字符串,用来标识本次客户端向服务器请求的id值.
  • command是命令关键词,类似于接口中的url,后端根据此标识来决定返回接口数据.
  • data是发送的参数.

前端向后端发起请求时,以上3个参数都得携带,其他参数可根据业务需要增添.

后端主动向前端推送消息时,只需要发送commanddata参数即可.客户端监听command,根据值的不同进行相应的操作.

在整个项目的通信架构下,前端需要搭建好以下两种通信机制.

  • 客户端向服务器发送请求,服务器处理请求并返回响应结果,客户端接受响应结果再做后续处理.这种机制模拟了类似于前端ajax的通信方式,客户端除了发送请求,还要负责接受该请求的响应.

  • 服务器主动向客户端推送消息,客户端接受消息.

以上两种机制基本满足了开发的需要,接下来在项目实战中实现以上两种机制(源代码贴在了文章结尾).

登录功能

登录页如下,页面内容很简答,两个输入框,输入账号和密码.还有一个登录按钮.

鼠标点击登录按钮时,dispatch触发LoginAction,此时客户端向服务器发起登录请求,请求成功后进入then的回调函数,打印出登录成功并且路由跳转到首页home.

import { LoginAction } from "../../redux/actions/login"; 

export default function Login() {

  const dispatch = useDispatch();
  const history = useHistory();
  
  //省略
  ...
  
  //登录
  const login = ()=>{
    dispatch(LoginAction()).then(()=>{
      console.log("登录成功!");
      history.push("/home");
    })
  }

  return (
          <div>
            <ul>
              <li>登录账号:</li>
              <li>
                  <div><input onChange={updateUser} type="text" placeholder="请输入账号" /></div>
              </li>
              <li>登录密码:</li>
              <li>
                  <div><input onChange={updatePwd} type="text" placeholder="请输入密码" /></div>
              </li>
            </ul>
            <button onClick={login}>立即登录</button>
          </div>  
  )
}

现在进入LoginAction函数的内部实现,探索它是如何实现发起请求 - 接受响应(代码如下).

LoginAction内部调用了fetch函数,actiontype值为"PUSH_MESSAGE".

从这里大概可以推断出fetch内部调用了dispatch,派发了一个type"PUSH_MESSAGE"action.

另外fetch函数返回了一个Promise,在then回调函数里接受后端返回的响应.

import { fetch } from "./global";

// 组装action数据类型
const loginType = (username,password)=>{
    return {
        type:"PUSH_MESSAGE", // 实际开发中这里应该用变量替代
        value:{
            command:"login",
            data:{
                username,
                password
            }
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值