Spring WebSocket简单入门测试Demo(网页及时聊天)

说明

本demo运行的环境是:ssm框架 + tomcat8 + jdk7+,由于只是demo。很简陋。能运行调式通过就行,再在此基础上进行扩展研究。

在网上看了很多列子。对于没有接触过websocket的人来说。真的是看不懂。本文列子应该算是比较简单的。

Spring WebSocket API的核心接口是WebSocketHandler。我把它叫做消息处理中心。

其他的详细解说可以参考别人的博客

    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
mvc的url-pattern 配置成 /  应该是拦截所有的访问请求?如果controller中有对应的地址就处理,没有就放行? 这一块不是太明白

pom.xml,版本自行查找。spring4.0+以上,在部署项目的时候。记得把tomcat8加入到jar包库(在eclipse中就是那个build path 中的 libraries )

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
        </dependency>

WebSocketConfig 配置

  由于之前使用xml配置,和springmvc中的地址冲突(忘记了是什么情况下发生的了,有可能是我访问地址访问错了)。就使用了注解配置类的形式配置

import cn.zymx.webTM.web.controller.HandshakeInterceptor;
import cn.zymx.webTM.web.controller.WebSocketHander;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**
* Created by zhuqiang on 2015/6/23 0023.
        */
@Configuration
@EnableWebSocket//开启websocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new WebSocketHander(),"/echo").addInterceptors(new HandshakeInterceptor()); //支持websocket 的访问链接
        registry.addHandler(new WebSocketHander(),"/sockjs/echo").addInterceptors(new HandshakeInterceptor()).withSockJS(); //不支持websocket的访问链接
    }
}

HandshakeInterceptor 拦截器

import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.socket.WebSocketHandler;

import javax.servlet.http.HttpSession;
import java.util.Map;

/**
 * Created by zhuqiang on 2015/6/22 0022.
 */
public class HandshakeInterceptor implements org.springframework.web.socket.server.HandshakeInterceptor {

    //进入hander之前的拦截
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Map<String, Object> map) throws Exception {
        if (request instanceof ServletServerHttpRequest) {
            ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
            HttpSession session = servletRequest.getServletRequest().getSession(false);
            String userName = "xq";
            if (session != null) {
                //使用userName区分WebSocketHandler,以便定向发送消息
//                String userName = (String) session.getAttribute("WEBSOCKET_USERNAME");
                map.put("WEBSOCKET_USERNAME",userName);
            }
        }
        return true;
    }

    @Override
    public void afterHandshake(ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse, WebSocketHandler webSocketHandler, Exception e) {

    }
}

WebSocketHandler 消息处理中心

import org.apache.log4j.Logger;
import org.springframework.web.socket.*;

import java.io.IOException;
import java.util.ArrayList;

/**
 * Created by zhuqiang on 2015/6/22 0022.
 */
public class WebSocketHander implements WebSocketHandler {
    private static final Logger logger = Logger.getLogger(WebSocketHander.class);

    private static final ArrayList<WebSocketSession> users = new ArrayList<>();

    //初次链接成功执行
    @Override
    public void afterConnectionEstablished(WebSocketSession session) throws Exception {
        logger.debug("链接成功......");
        users.add(session);
        String userName = (String) session.getAttributes().get("WEBSOCKET_USERNAME");
        if(userName!= null){
            //查询未读消息
            int count = 5;
            session.sendMessage(new TextMessage(count + ""));
        }
    }

    //接受消息处理消息
    @Override
    public void handleMessage(WebSocketSession webSocketSession, WebSocketMessage<?> webSocketMessage) throws Exception {
        sendMessageToUsers(new TextMessage(webSocketMessage.getPayload() + ""));
    }

    @Override
    public void handleTransportError(WebSocketSession webSocketSession, Throwable throwable) throws Exception {
        if(webSocketSession.isOpen()){
            webSocketSession.close();
        }
        logger.debug("链接出错,关闭链接......");
        users.remove(webSocketSession);
    }

    @Override
    public void afterConnectionClosed(WebSocketSession webSocketSession, CloseStatus closeStatus) throws Exception {
        logger.debug("链接关闭......" + closeStatus.toString());
        users.remove(webSocketSession);
    }

    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
    /**
     * 给所有在线用户发送消息
     *
     * @param message
     */
    public void sendMessageToUsers(TextMessage message) {
        for (WebSocketSession user : users) {
            try {
                if (user.isOpen()) {
                    user.sendMessage(message);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 给某个用户发送消息
     *
     * @param userName
     * @param message
     */
    public void sendMessageToUser(String userName, TextMessage message) {
        for (WebSocketSession user : users) {
            if (user.getAttributes().get("WEBSOCKET_USERNAME").equals(userName)) {
                try {
                    if (user.isOpen()) {
                        user.sendMessage(message);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                break;
            }
        }
    }
}

页面

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
    <!-- 新 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
    <!-- 可选的Bootstrap主题文件(一般不用引入) -->
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap-theme.min.css">
    <!-- jQuery文件。务必在bootstrap.min.js 之前引入 -->
    <script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
    <!--<script type="text/javascript" src="js/jquery-1.7.2.js"></script>-->
    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <title>webSocket测试</title>
    <script type="text/javascript">
        $(function(){
            var websocket;
            if (‘WebSocket‘ in window) {
                alert("WebSocket");
                websocket = new WebSocket("ws://127.0.0.1:8080/echo");
            } else if (‘MozWebSocket‘ in window) {
                alert("MozWebSocket");
                websocket = new MozWebSocket("ws://echo");
            } else {
                alert("SockJS");
                websocket = new SockJS("http://127.0.0.1:8080/sockjs/echo");
            }
            websocket.onopen = function (evnt) {
                $("#tou").html("链接服务器成功!")
            };
            websocket.onmessage = function (evnt) {
                $("#msg").html($("#msg").html() + "<br/>" + evnt.data);
            };
            websocket.onerror = function (evnt) {
            };
            websocket.onclose = function (evnt) {
                $("#tou").html("与服务器断开了链接!")
            }
            $(‘#send‘).bind(‘click‘, function() {
                send();
            });
            function send(){
                if (websocket != null) {
                    var message = document.getElementById(‘message‘).value;
                    websocket.send(message);
                } else {
                    alert(‘未与服务器链接.‘);
                }
            }
        });
    </script>

</head>
<body>

<div class="page-header" id="tou">
    webSocket及时聊天Demo程序
</div>
<div class="well" id="msg">
</div>
<div class="col-lg">
    <div class="input-group">
        <input type="text" class="form-control" placeholder="发送信息..." id="message">
      <span class="input-group-btn">
        <button class="btn btn-default" type="button" id="send" >发送</button>
      </span>
    </div><!-- /input-group -->
</div><!-- /.col-lg-6 -->
</div><!-- /.row -->
</body>

</html>

时间: 2024-10-05 11:58:39

Spring WebSocket简单入门测试Demo(网页及时聊天)的相关文章

spring mvc开发入门实例demo源代码下载,很适合新手入门学习用。

原文:spring mvc开发入门实例demo源代码下载,很适合新手入门学习用. 源代码下载:http://www.zuidaima.com/share/1550463469046784.htm Eclipse + Maven + Spring MVC - Simple Example 源代码框架截图:

websocket简单入门

今天说起及时通信的时候,突然被问到时用推的方式,还是定时接受的方式,由于之前页面都是用传统的ajax处理,可能对ajax的定时获取根深蒂固了,所以一时之间没有相同怎么会出现推的方式呢?当被提及websocket的时候突然头脑中搭上了这根线.一.WebSocket是HTML5出的东西(协议),也就是说HTTP协议没有变化,或者说没关系,但HTTP是不支持持久连接的(长连接,循环连接的不算)首先HTTP有1.1和1.0之说,也就是所谓的keep-alive,把多个HTTP请求合并为一个,但是Webs

Spring.Net 简单入门学习

Spring.NET IoC容器的用法. 通过简单的例子学习Spring.Net 1.先创建一个控制台程序项目. 2.添加IUserInfoDal 接口. namespace Spring.Net { public interface IUserInfoDal { void Show(); } } 3.添加AdoNetUserInfoDal类和EFUserInfoDal类,继承IUserInfoDal接口. AdoNetUserInfoDal.cs public class AdoNetUser

spring boot简单的小demo(适合于初学者)

import com.example.demo2.com.example.dao.ShopDao; import com.example.demo2.com.example.entity.Shops; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.RequestMapping; import org.springframew

Spring MVC 简单入门

web.xml 配置: <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <description>加载/WEB-INF/spring-mvc/目录下的所有XML作为Spring MVC的

websocket的php测试demo

<?php class WS { var $master; var $sockets = array(); var $debug = false; var $handshake = false; function __construct($address, $port){ $this->master=socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("socket_create() failed"); socket_se

FastDFS简单入门小demo

图片上传 需要引入 FastDFS 相关的jar包,但是这个jar没有在中央仓库,所以还得需要找到这个jar手动安装到自己的本地仓库才能使用. 需要一个配置文件   fdfs_client.conf 需要一个 FastDFS 服务器 看代码: fdfs_client.conf # connect timeout in seconds # default value is 30s connect_timeout=30 # network timeout in seconds # default v

spring AOP 简单入门案例

TestServiceinter.java 1 package com.frank.aop; 2 3 public interface TestServiceinter { 4 public void SayHello(); 5 6 } TestServiceImp.java 1 package com.frank.aop; 2 3 public class TestServiceImp implements TestServiceinter { 4 5 private String name;

gulp安装+一个超简单入门小demo

gulp安装參考.gulp安装參考2. 一.NPM npm是node.js的包管理工具.主要功能是管理.更新.搜索.公布node的包. Gulp是通过npm安装的. 所以首先,须要安装node.js.而且升级npm到最新版本号. 安装nodeJS 基本參考传送门戳这里:安装nodeJs.安装nodeJs2.nodeJs下express的安装到执行 1.    从nodejs.org下载最新的nodejs安装包.并安装. 2.    进入nodejs的安装路径下: 天真的以为这样就能够了. wat