浅析websocket与websocket连接数测试

来源:互联网 发布:红警2单位数据 编辑:程序博客网 时间:2024/05/29 13:43

       WebSocket是html5新增加的一种通信协议,我们知道HTTP协议是一种单向的网络协议,在建立连接后,它只允许浏览器客户端向WebServer发出请求资源后,WebServer才能返回相应的数据。即WebServer不能主动的推送数据,但是面对在web系统上实时聊天的这类需求,基于HTTP协议实现会很麻烦,公司项目组开发的在线客服系统中也有这样的需求,为了更好地实现,采用的是websocket技术。而测试系统的websocket的性能也是我的工作之一。

一、websocket简介
       WebSocket协议是一种双向通信协议,它建立在TCP之上,同http一样通过TCP来传输数据,都是可靠的连接,但是它和http最大的不同有两点:
       1.WebSocket是一种双向通信协议,在建立连接后,WebSocket服务器和Browser/UA都能主动的向对方发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的一种简单模拟Socket的协议;
       2.WebSocket需要通过握手连接,类似于TCP它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。
  
       那么建立一个websocket连接,是一个怎么样的握手过程呢,(总共4次哦)首先进行TCP的连接,三次握手成功后再进行一次websocket的握手:
       Browser/UA通过http协议传送WebSocket支持的版本号,协议的字版本号,原始地址,主机地址等等一些列字段给服务器端;
       WebSocket服务器收到Browser/UA发送来的握手请求后,如果数据包数据和格式正确,客户端和服务器端的协议版本号匹配等等,就接受本次握手连接,并给出相应的数据采用http协议传输回复,
        Browser收到服务器回复的数据包后,如果数据包内容、格式都没有问题的话,就表示本次连接成功,触发onopen消息,此时Web开发者就可以在此时通过send接口想服务器发送数据。否则,握手连接失败。
        另外,搭建websocket的服务器比较困难,可以利用一些开源库,直接调用其中解析和封装websocket数据的接口,会轻松很多。

二、websocket性能测试
    对于基于websocket协议的在线聊天的系统来说,得保证其稳定性,连接数作为性能指标,测试websocket的并发连接数非常重要,另外还有连接能力,就是模拟测试websocket并发地发送消息。而用一般的web测试工具无法测,需要编写测试脚本进行自动化测试(有大神协助。。。)
    测试websocket的连接数就是同时开启多个线程,调用websocket的API进行连接建立,测出最大连接数(并发连接数),并用日志记录连接情况。
      在建立websocket连接时,首先获取登陆认证的唯一ticket(类似登陆用户的ID),cookies,HTTP协议版本以及服务器地址、websocket接口等,加到websocket的请求报文中,发起连接,接收到接受服务器的响应ACK内容,则连接成功。
      下面是部分go语言实现的主要代码
<span style="font-size:18px;"> func main() {    var wg sync.WaitGroup    var index = 0    // var temp = 0    for _, empCode := range EmpCodes {//依次开启每个账号的线程        index = index + 1        if index > 1 {        break    }    log.Printf("index:%v", index)    wg.Add(1)</span>
<span style="font-size:18px;">    go func(code string) {       defer wg.Done()       err := SimulateKeepOnline(code)//调用建立websocket连接的方法       if err != nil {           log.Printf("[%s] has error: %s", code, err.Error())           return       }    }(empCode)  }  wg.Wait()//并发启动线程}func SimulateKeepOnline(empCode string) error {    log.Printf("[%s] Begin...", empCode)    defer log.Printf("[%s] Exit...", empCode)    ticket, err := ConnectorAuth(empCode)    if err != nil {      return err    }    // Extract the cookie for later use    log.Printf("[%s] Establishing websocket connection...", empCode)    // Establish websocket connection    var wsHeader = http.Header(make(map[string][]string))    cookie := http.Cookie{        Name:  "WS_TICKET",        Value: ticket,    }    wsHeader.Add("Cookie", cookie.String())    //服务器地址    wsConfig, err := NewConfig("ws://ws.xxx.cn/employee/ws", "http://ws.xxx.cn")    if err != nil {        return err    }    wsConfig.Header = wsHeader    wsConn, err := DialConfig(wsConfig)    if err != nil {        return err    }    log.Printf("[%s] IsClientConn: %v", empCode, wsConn.IsClientConn())    log.Printf("[%s] IsServerConn: %v", empCode, wsConn.IsServerConn())    log.Printf("[%s] LocalAddr: %+v", empCode, wsConn.LocalAddr())    log.Printf("[%s] RemoteAddr: %+v", empCode, wsConn.RemoteAddr())    log.Printf("[%s] Receiving upstream messages...", empCode)    for {        var message string        //接受服务器发送的响应ACK        if err := Message.Receive(wsConn, &message); err != nil {            return err            continue        }        log.Printf("[%s] received: %s", empCode, message)    }}</span>

      而测试连接能力是用代码模拟在websocket并发地发送消息,在建立websocket连接之后,可以开始向服务器发送消息,通过日志记录检测并发地发送消息时系统是否报错。
0 2
原创粉丝点击