websocket服务端开发

Posted lccsblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了websocket服务端开发相关的知识,希望对你有一定的参考价值。

基于http请求以拉的方式去做服务器的推送,无论是实时性和有效字节都是差强人意的效果。

公司的im系统在与客户端的交互上实际上借助了websocket来实现服务器与客户端的事实消息推送,今天就来简单了解下这个协议,并且自己实现对websocket的响应。

 

技术图片

可以看到在理解了tcp和http之后,websocket的设计其实并不复杂,再最开始建立链接的时候客户端实际上会进行一次http请求,只不过请求头的内容有些特别,这里我们来看下:

GET /chat HTTP/1.1

Host: server.example.com

Upgrade: websocket

Connection: Upgrade

Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==

Origin: http://example.com

Sec-WebSocket-Protool: chat,superchat

Sec-WebSocket-Version:13

可以看到这个报文里包含了一些附加头信息。其中附加头信息"Upgrade: WebSocket" ,表明这是一个申请协议升级的http请求。"Sec-WebSocket-Key"是随机的,服务端会用这些数据构造出

一个SHA-1的信息摘要,把"Sec-WebSocket-Key"加上一个魔幻字符串"258EAFA5-E914-47DA-95CA-C5AB0DC85B11"。使用SHA-1加密,然后进行BASE-64编码,将结果作为"Sec-WebSocket-Accept"头的值,返回给客户端:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=
Sec-WebSocket-Protool: chat

实现对websocket请求的响应:

public class WebsocketServer 
    public static void main(String[] args) throws IOException 
        ServerSocket serverSocket=new ServerSocket(8080);
        Socket socket= serverSocket.accept();
        new Thread(new Handle(socket)).start();
    
public class Handle implements Runnable
    private Socket socket;

    Handle(Socket socket)
        this.socket=socket;
    

    @Override
    public void run() 
        try 
            BufferedReader reader=new BufferedReader(new InputStreamReader(socket.getInputStream()));
            OutputStreamWriter streamWriter=new OutputStreamWriter(socket.getOutputStream());
            BufferedWriter bufferedWriter=new BufferedWriter(streamWriter);
            String key=null;
            //读报文
            while (true)
               String s= reader.readLine();
               System.out.println(s);
                if (s.equals(""))
                   break;
                else
                    if (s.contains("Sec-WebSocket-Key"))
                        String keyValue[]=s.split(":");
                        key=keyValue[1].trim()+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
                    
                
            
            //写报文
            MessageDigest messageDigest=DigestUtils.getSha1Digest();
            byte[] key2=messageDigest.digest(key.getBytes());
            Base64 base64 = new Base64();
            String finalKey=base64.encodeToString(key2);
            bufferedWriter.write("HTTP/1.1 101 Switching Protocols\\r\\n");
            bufferedWriter.write("Upgrade: websocket\\r\\n");
            bufferedWriter.write("Connection: Upgrade\\r\\n");
            bufferedWriter.write("Sec-WebSocket-Accept: "+finalKey+"\\r\\n");
            bufferedWriter.write("Sec-WebSocket-Protool: chat\\r\\n");
            bufferedWriter.write("\\r\\n");
            bufferedWriter.write("test");
            bufferedWriter.write("\\r\\n");
            bufferedWriter.flush();
            //接收数据
            System.out.println("响应报文已经发送");
            while (true)
                Thread.sleep(2000);
                String s=reader.readLine();
                System.out.println(s==null);
            
         catch (IOException e) 
            e.printStackTrace();
         catch (InterruptedException e) 
            e.printStackTrace();
        

    

 

以上是关于websocket服务端开发的主要内容,如果未能解决你的问题,请参考以下文章

apache配置反向代理+websocket

基于node.js 的 websocket的移动端H5直播开发

即时通讯开发中WebSocket和SSE技术如何实现Web端消息推送

Java web 服务端消息推送用啥比较好

Pywss - 用python实现WebSocket服务端

IM即时通讯开发新手快速入门:WebSocket教程