websocket(一)--原生websocket使用

websocket(一)–原生websocket使用

一、简介

websocket可以在单tcp连接上进行全双工通信协议,即是服务端和客户端间可双向通信。这里对原生的websocket
使用进行示例介绍(需要新版浏览器支持)。

二、java端关键点

2.1 ServerEndpointExporter

ServerEndpointExporter,即org.springframework.web.socket.server.standard.ServerEndpointExporter,用于检测和注册以@ServerEndpoint注解的websocket endpoints。

2.2 Session

Session,即javax.websocket.Session,会话类,记录会话相关信息。

2.3 @ServerEndpoint

注解在类上,配置websocket endpoints,设置websocket连接地址。

2.4 处理方法

在endpoints类中,使用注解在方法,对连接过程进行处理。

  • @OnOpen:websocket连接时处理器;
  • @OnMessage:消息处理;
  • @OnError:连接出错处理;
  • @OnClose:连接失败处理;

三、前端关键点

3.1 websocket地址

以ws或wss开头,如:

var url = "ws://localhost:8080/talk_websocket/"

3.2 创建连接

使用WebSocket对象创建连接,如:

var webSocket = new WebSocket(url);

3.3 处理方法

  • webSocket.onopen:连接建立;
  • webSocket.onmessage:接收消息;
  • webSocket.onerror: 连接出错;
  • webSocket.onclose: 关闭连接;

四、 使用示例

这里使用spring boot,以聊天室为例进行示例。

4.1 添加maven依赖

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-websocket</artifactId>
</dependency>

4.2 生成spring boot 启动类

package com.dragon.websocket_study;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

4.3 定义spring web mvc配置类

package com.dragon.websocket_study.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
    /
     * 检测和注册endpoints
     * @return
     */
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }

    /
     * 添加静态文件
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/static/").addResourceLocations("classpath:/static/");
    }
}

4.4 配置endpoint类及相关处理方法

package com.dragon.websocket_study.websocket;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/talk_websocket/{uid}")  //websocket连接地址
@Component
public class TalkWebSocketEndpoint {

    //记录会话
    private static ConcurrentHashMap<String, Session> sessionMap = new ConcurrentHashMap<>();

    /
     * 连接时处理类
     * @param uid
     * @param session
     * @throws IOException
     */
    @OnOpen
    public void onOpen(@PathParam("uid") String uid, Session session) throws IOException {
        sessionMap.put(uid, session);
        session.getBasicRemote().sendText("welcome to talk");
    }

    /
     * 接收消息处理类
     * @param uid
     * @param message
     * @param session
     * @throws IOException
     */
    @OnMessage
    public void onMessage(@PathParam("uid") String uid, String message, Session session) throws IOException {
        for (Map.Entry<String, Session> entry : sessionMap.entrySet()) {
            entry.getValue().getBasicRemote().sendText(message);
        }
    }

    /
     * 出错处理器
     * @param uid
     * @param e
     */
    @OnError
    public void onError(@PathParam("uid") String uid, Throwable e) {
        sessionMap.remove(uid);
    }

    /
     * 连接失败处理器
     * @param uid
     * @param session
     * @param reason
     */
    @OnClose
    public void onClose(@PathParam("uid") String uid, Session session, CloseReason reason) {
        sessionMap.remove(uid);
    }
}

4.5 配置页面controller类

package com.dragon.websocket_study.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
@RequestMapping("rawWebSocket")
public class RawWebSocketController {

    @RequestMapping("talk/{uid}")
    public String talkWebsocket(Model model, @PathVariable String uid) {
        model.addAttribute("uid", uid);
        return "talk_websocket";
    }
}

4.6 前端添加jquery

请自行下载jquery-3.1.1.min.js

4.7 thymeleaf页面代码

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>

    <style>
        #historyId {
            border: 1px black solid;
            height: 370px;
            width: 500px;
            overflow-y: scroll;
            word-break: break-all;
        }

        #msgId {
            width: 500px;
            height: 130px;
        }

        #talkId {
            /*text-align: center;*/
        }
    </style>

</head>
<body>
<section id="talkId">
    <header>
        tip:<span id="tipId" th:text="${uid}"></span>
    </header>

    <article id="historyId">

    </article>
    <article>
        <textarea id="msgId"></textarea>
    </article>
    <footer>
        <button id="sendId">send</button>
        <button id="closeId">close</button>
        <button id="clearId">clear</button>
        <button id="connectId">connect</button>
    </footer>
</section>

<script th:src="@{/static/js/jquery-3.1.1.min.js}"></script>
<script th:inline="javascript">
    $(function () {
        if('WebSocket' in window){
            console.log("support websocket");
        }else{
            console.log("not support websocket");
        }

        var webSocket;
        var initWebSocket = function (uid) {
            var url = "ws://" + window.location.host + "/talk_websocket/" + [[${uid}]];
            webSocket = new WebSocket(url);

            //连接建立
            webSocket.onopen = function (event) {
                $("#tipId").html("connect success");
            };

            //接收消息
            webSocket.onmessage = function (event) {
                $("#historyId").append("<p>" + event.data + "</p>");
                $("#historyId").scrollTop($("#historyId")[0].scrollHeight);
            };

            //连接出错
            webSocket.onerror = function (e) {
                $("#tipId").html("connect error");
            };

            //关闭连接
            webSocket.onclose = function (e) {
                $("#tipId").html("connect close");
            };
        };

        var sendMsg = function () {
            var msg = $("#msgId").val();
            console.log("send msg : " + msg);
            webSocket.send(msg);
            $("#msgId").val("")
        };

        //点按钮发送消息
        $("#sendId").click(function () {
            sendMsg();
        });

        //回车发消息
        $(document).keyup(function (e) {
            if (e.keyCode == 13) {
                sendMsg();
            }
        });

        //清空记录
        $("#clearId").click(function () {
            $("#historyId").empty();
        });

        //连接
        $("#connectId").click(function () {
            initWebSocket($("#uid").val())
        });

        //关闭连接
        $("#closeId").click(function () {
            webSocket.close();
        });

        $("#historyId").scrollTop($("#historyId")[0].scrollHeight);
    })
</script>
</body>
</html>

至此,使用websocket开发的简单聊天室完成。
运行WebsocketStudyApplication类,访问http://localhost:8080/rawWebSocket/talk/1地址即可。

发布了274 篇原创文章 · 获赞 95 · 访问量 50万+

猜你喜欢

转载自blog.csdn.net/chinabestchina/article/details/105039085
今日推荐