第二章 WebSocket简单实现

HTTP

http协议是短链接,因为请求之后,都会关闭连接,下次重新请求数据,需要再次打开链接

WebSocke

1.定义 :WebSocket 是HTML5的新协议,它实现了浏览器与服务器全双工通信(full-duplex),一开始的握手需要借助HTTP请求完成。WebSocket是真正实现了全双工通信的服务器项客户端推送的互联网技术。它是在一种单个TCP连接上进行全双工通讯协议。WebSocket通信协议与2011年被IEFT定为标准RFC6455,WebSocketAPI 被W3C定为标准。

  1. 查询支持的浏览器: https://caniuse.com/#search=websocket
    服务端支持: Tomcat 7.0.47+以上才支持

  2. websocket 的相关注解说明
    @ServerEndpoint("/websocket/{uid}")
    3.1 申请这是一个websocket服务
    3.2 需要指定访问该服务的地址,在地址中可以指定参数,需要通过{}进行占位
    @OnOpen
    用法: public void onOpen(Session session,@PathParam(“uid”) String uid) throws IOException{}
    该方法在建立连接后执行,会传入session对象,就是客户端与服务端建立的长连接通道
    通过@PathParam获取Url申明的参数
    @Close
    用法:public void onClose(){}
    该方法是在连接关闭后执行
    @OnMessage
    用法: public void onMessage(String message,Session session) throws IOException{}
    该方法用于接收客户端发来的消息
    message: 发来的消息数据
    session:会话对象(也是通道)
    发送消息到客户端
    用法: session.getBasicRemote().sendText(“你好”)
    通过session进行发送

快速入门
创建工程,引入依赖

<dependencies>
  <dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>7.0</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

<build>
  <plugins> <!-- java编译插件 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.2</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
      </configuration>
    </plugin> <!-- 配置Tomcat插件 -->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <port>9082</port>
        <path>/</path>
      </configuration>
    </plugin>
  </plugins>
</build>

创建类:com.sharpnew.websocket.MyWebSocket
编写实现类

@ServerEndpoint("/websocket/{uid}")
public class MyWebSocket {
     
  /*
  打开
   */
  @OnOpen
  public void onOpen(Session session,@PathParam("uid") String uid) throws IOException {
     
    System.out.println("websocket已经连接" + session);
    //给客户端响应,欢迎登录
    session.getBasicRemote().sendText(uid+"欢迎登录系统");
  }
  /*
  关闭
   */
  @OnClose
  public void onClose(Session session) {
     
    System.out.println("websocket已经关闭" + session);
  }
  /*
  客户发来消息
   */
  @OnMessage
  public void onMessage(String message, Session session) throws IOException {
     
    System.out.println("收到客户端发来的消息--->" + message);
    try {
     
      Thread.sleep(200);
    } catch (InterruptedException e) {
     
      e.printStackTrace();
    }
    session.getBasicRemote().sendText("消息已收到");
  }
}

启动tomcat ,然后 maven Projects—> Plugins->tomcat7:run
在线测试工具:
http://www.easyswoole.com/wstool.html

  1. 新建客户端页面 -> webapp->index.html
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<script>
    const socket = new WebSocket("ws://localhost:9082/websocket/1");
    socket.onopen = (ws) => {
     
        console.log("建立连接");
    }
    socket.onclose = (ws) => {
     
        console.log("关闭连接");
    }
    socket.onmessage = (ws) => {
     
        console.log("接收到消息", ws.data);
    }
    socket.onerror = (ws) => {
     
        console.log("发送错误", ws);
    }
    setTimeout(()=>{
     
        socket.send("发送一条消息试试");
    },2000);
    setTimeout(()=>{
     
        socket.close();
    },5000);
</script>
</html>

springBoot 整合WebSocket

  1. 新建模块(spring-websocket)-》导入依赖
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>2.2.5.RELEASE</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-websocket</artifactId>
<dependencies>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
  </dependency>
</dependencies>
<build>
  <plugins> <!-- java编译插件 -->
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.2</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
      </configuration>
    </plugin> <!-- 配置Tomcat插件 -->
    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.2</version>
      <configuration>
        <port>8082</port>
        <path>/</path>
      </configuration>
    </plugin>
  </plugins>
</build>

2.继承方法并重写

//注入容器中
@Component
public class MyHandler extends TextWebSocketHandler {
     
  @Override
  public void handleTextMessage(WebSocketSession session, TextMessage message) throws IOException {
     
    System.out.println("获取到消息 >> " + message.getPayload());
    session.sendMessage(new TextMessage("消息已收到"));
    //当消息等于10,输出0-9
    if (message.getPayload().equals("10")) {
     
      for (int i = 0; i < 10; i++) {
     
        session.sendMessage(new TextMessage("消息 -> " + i));
        try {
     
          Thread.sleep(100);
        } catch (InterruptedException e) {
     
          e.printStackTrace();
       }
      }
    }
  }
  @Override
  public void afterConnectionEstablished(WebSocketSession session) throws Exception {
     
    session.sendMessage(new TextMessage("欢迎连接到ws服务"));
  }
  @Override
  public void afterConnectionClosed(WebSocketSession session, CloseStatus status) throws Exception {
     
    System.out.println("断开连接!");
  }
}
  1. 添加配置类,注册MyHandler
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
     
  @Autowired
  private MyHandler myHandler;
  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
     
    //所有地址可以跨域setAllowedOrigins("*")
    registry.addHandler(this.myHandler, "/ws").setAllowedOrigins("*");
  }
}

4.编写启动类

@SpringBootApplication
public class MyApplication {
     
  public static void main(String[] args) {
     
    SpringApplication.run(MyApplication.class, args);
  }
}

websocket拦截器
在spring 中提供了websocket拦截器,可以在建立连接之前写些业务逻辑,比如验证登录等。

1.编写拦截器实现类

@Component
public class MyHandshakeInterceptor implements HandshakeInterceptor {
     
  /*
  握手之前,若返回false,则不建立连接
   */
  @Override
  public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
     
    //将用户id放入socket处理器的会话(WebSocketSession)中
    attributes.put("uid", 1001);
    System.out.println("开始握手。。。。。。。");
    return true;
  }
  @Override
  public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse
      serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {
     
    System.out.println("握手成功............");
  }
}
  1. 将拦截器添加到websocket服务中
@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
     
  @Autowired
  private MyHandler myHandler;
  @Autowired
  private MyHandshakeInterceptor myHandshakeInterceptor;
  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
     
    //所有地址可以跨域setAllowedOrigins("*")
    registry.addHandler(this.myHandler, "/ws").setAllowedOrigins("*").addInterceptors(this.myHandshakeInterceptor);
  }
}

你可能感兴趣的:(JAVA,#,网络通信,socket,java)