初识websocket

一、定义


websocket.jpg

WebSocket协议是基于TCP的一种新的网络协议。它实现了浏览器与服务器全双工(full-duplex)通信——允许服务器主动发送信息给客户端。
WebSocket协议支持(在受控环境中运行不受信任的代码的)客户端与(选择加入该代码的通信的)远程主机之间进行全双工通信。
二、产生的背景
简单的说,WebSocket协议之前,双工通信是通过不停发送HTTP请求,从服务器拉取更新来实现,这导致了效率低下。WebSocket解决了这个问题
三、解决的问题
1.服务器被迫为每个客户端使用许多不同的底层TCP连接:一个用于向客户端发送信息,其它用于接收每个传入消息。
2.有些协议有很高的开销,每一个客户端和服务器之间都有HTTP头。
3.客户端脚本被迫维护从传出连接到传入连接的映射来追踪回复。
四、实现原理和好处
1、原理:在实现websocket连线过程中,需要通过浏览器发出websocket连线请求,然后服务器发出回应,这个过程通常称为“握手” 。
2、好处
① Header
互相沟通的Header是很小的-大概只有 2 Bytes
②Server Push
服务器的推送,服务器不再被动的接收到浏览器的请求之后才返回数据,而是在有新数据时就主动推送给浏览器。

五、请求响应案例
浏览器请求
GET /webfin/websocket/ HTTP/1.1

Host: localhost
  Upgrade: websocket

Connection: Upgrade
  Sec-WebSocket-Key: xqBt3ImNzJbYqRINxEFlkg==
  Origin: http://服务器地址
  Sec-WebSocket-Version: 13

服务器回应
HTTP/1.1 101 Switching Protocols
  Upgrade: websocket
  Connection: Upgrade
  Sec-WebSocket-Accept: K7DJLdLooIwIG/MOpvWFB3y3FE8=
WebSocket借用http请求进行握手,相比正常的http请求,多了一些内容。
其中,Upgrade: websocket
Connection: Upgrade
表示希望将http协议升级到Websocket协议。
Sec-WebSocket-Key是浏览器随机生成的base64 encode的值,用来询问服务器是否是支持WebSocket。

服务器返回
Upgrade: websocket
Connection: Upgrade
告诉浏览器即将升级的是Websocket协议
Sec-WebSocket-Accept是将请求包“Sec-WebSocket-Key”的值,与”258EAFA5-E914-47DA-95CA-C5AB0DC85B11″这个字符串进行拼接,然后对拼接后的字符串进行sha-1运算,再进行base64编码得到的。用来说明自己是WebSocket助理服务器。

六、个人demo
1.服务端
/*

  • websocket服务端

  • 客户端向服务器端建立websocket的url

  • */
    @ServerEndpoint("/websocket")
    @Component
    public class WebSocketServer {
    //计算当前在线人数
    private static int onlineCount=0;
    //concurrent包的线程安全set,用来存放每个客户端对应的mywebsocket对象,必须
    private static CopyOnWriteArraySetwebSocketSet=new CopyOnWriteArraySet<>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据,必须
    private Session session;

    /*

    • 连接建立成功使用的方法
    • /
      @OnOpen
      public void onOpen(Session session){
      this.session=session;
      webSocketSet.add(this);
      addOnlineCount(); //在线数加1
      System.out.println("有新窗口开始监听,当前在线人数为" + getOnlineCount());
      try {
      sendMessage("连接成功");
      } catch (IOException e) {
      System.out.println("WebSocket IO异常");
      }
      }
      /

      连接关闭调用的方法
      /
      @OnClose
      public void onClose() {
      webSocketSet.remove(this); //从set中删除
      subOnlineCount(); //在线数减1
      System.out.println("有连接关闭!当前在线人数为" + getOnlineCount());
      }
      /
    • 收到客户端消息后调用的方法
    • @param message 客户端发送过来的消息
      /
      @OnMessage
      public void onMessage(String message, Session session) {
      System.out.println("收到客户端的信息:" + message);
      //群发消息
      for (WebSocketServer item : webSocketSet) {
      try {
      item.sendMessage(message);
      } catch (IOException e) {
      e.printStackTrace();
      }
      }
      }
      /
      *
    • @param session
    • @param error
      */
      @OnError
      public void onError(Session session, Throwable error) {
      System.out.println("发生错误");
      error.printStackTrace();
      }

    /**

    • 实现服务器主动推送
      */
      public void sendMessage(String message) throws IOException {
      this.session.getBasicRemote().sendText(message);
      }
/**
 * 群发自定义消息
 */
public static void sendInfo(String message) throws IOException {
    System.out.println("推送消息内容:" + message);
    for (WebSocketServer item : webSocketSet) {
        try {
            item.sendMessage(message);
        } catch (IOException e) {
            continue;
        }
    }
}

public static synchronized int getOnlineCount() {
    return onlineCount;
}

public static synchronized void addOnlineCount() {
    WebSocketServer.onlineCount++;
}

public static synchronized void subOnlineCount() {
    WebSocketServer.onlineCount--;
}

}
2.配置webSocket
/*

  • WEBSOCKET配置类

  • 开启websocket支持

  • */
    @Configuration
    public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
    return new ServerEndpointExporter();
    }
    }
    3.提供接口
    @RestController
    @RequestMapping(value = "/socket")
    public class WebSocketController {
    //推送数据接口
    @RequestMapping("/push")
    public String pushMsg(HttpServletRequest request) {
    String message=request.getParameter("info");
    try {
    WebSocketServer.sendInfo(message);
    } catch (IOException e) {
    e.printStackTrace();
    }
    return "success";
    }
    }
    4.主类
    @SpringBootApplication
    public class WebsocketApplication {

    public static void main(String[] args) {
    SpringApplication.run(WebsocketApplication.class, args);
    }
    }
    5.前端客户端




    websocket页面



    WebSocket练习




    消息显示区域










    服务器端广播消息区域







    6.前端服务器端




    server页面



    服务器推送消息




你可能感兴趣的:(初识websocket)