spring+webscoket注解方式

WebSocket 是 HTML5 一种新的协议。它实现了浏览器与服务器全双工通信,能更好的节省服务器资源和带宽并达到实时通讯,它建立在 TCP 之上,同 HTTP 一样通过 TCP 来传输数据,但是它和 HTTP 最大不同是:
WebSocket 是一种双向通信协议,在建立连接后,WebSocket 服务器和 Browser/Client Agent 都能主动的向对方发送或接收数据,就像 Socket 一样;
WebSocket 需要类似 TCP 的客户端和服务器端通过握手连接,连接成功后才能相互通信。

maven:


        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- spring4下的websocket默认使用jackson相关jar包,导入:  -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.6.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.5</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.5</version>
        </dependency>

绑定httpsession

package leo.util;  

import javax.servlet.http.HttpSession;
import javax.websocket.HandshakeResponse;
import javax.websocket.server.HandshakeRequest;
import javax.websocket.server.ServerEndpointConfig;  
//配置类  将http中的session传入websocket中  

public class GetHttpSessionConfigurator extends  
        ServerEndpointConfig.Configurator {  
    @Override  
    public void modifyHandshake(ServerEndpointConfig config,  
            HandshakeRequest request, HandshakeResponse response) {  
        HttpSession httpSession = (HttpSession) request.getHttpSession();  
        config.getUserProperties().put(HttpSession.class.getName(), httpSession);  
      //我也碰到这个坑,最后发现自己在浏览器登录的时候是用的localhost,但websocket连接的时候是用的本机Ip地址127.0.0.1
        //,所以握手拦截的时候,是得不到原来的session的,保证地址栏的请求和websocket的请求地址统一就能获取到了
    } 
}  

webscoket配置类

package leo.util;

import java.io.IOException;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.servlet.http.HttpSession;
import javax.websocket.CloseReason;
import javax.websocket.EndpointConfig;
import javax.websocket.OnClose;
import javax.websocket.OnError;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.ServerEndpoint;

import org.springframework.stereotype.Component;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

//注意此访问地址格式如:"ws://"+ window.location.host+"${pageContext.request.contextPath}/game"是ws开头的,而不是以http:开头的.
//, configurator = GetHttpSessionConfigurator.class
@ServerEndpoint(value = "/websocket",configurator = GetHttpSessionConfigurator.class)
@Component
@EnableWebSocketMessageBroker // @EnableWebSocketMessageBroker注解能够在WebSocket之上启用STOMP
public class Scoket {

    private Logger logger = Logger.getLogger(this.getClass().getName());

    private static Map<String, Session> sessionMap = new Hashtable<String, Session>();

    private static HttpSession httpSession;

    @OnOpen
    public void onOpen(Session session, EndpointConfig config) {
        httpSession = (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
        sessionMap.put((String) httpSession.getAttribute("user"), session);
        Set<Map.Entry<String, Session>> set = sessionMap.entrySet();
        System.out.println("在线人数:" + set.size());
        sendMessageToAll("系统提示:", httpSession.getAttribute("user") + "上线啦!");
    }

    @OnMessage
    public void onMessage(String content, Session session) throws IOException {
        System.out.println(session.getId() + " 开始广播:" + content);
        // getBasicRemote()能够同步地向对等点发送消息
         JSONObject json_test = JSONObject.parseObject(content); 
//       session.getBasicRemote().sendText("游客" + session.getId() + ":" +
//               json_test.get("message"));

//      HashMap<String, String> msgMap = new HashMap<String, String>();
//      if (!content.equals("")) {
//          msgMap = getMessage(content);
//          sendMessageToUser(msgMap.get("fromName"), msgMap.get("toName"), msgMap.get("content").toString());
//
//      }
        sendMessageToAll("leo",json_test.get("message").toString());
    }

    /**
     * 消息处理类,处理前端发来的消息
     * 
     * @param msg
     * @return
     */
    public static HashMap<String, String> getMessage(String msg) {
        HashMap<String, String> map = new HashMap<String, String>();
        String msgString = msg.toString();
        String m[] = msgString.split(",");
//      map.put("fromName", m[0]);
        map.put("toName", m[1]);
        map.put("content", m[2]);
        return map;
    }

    /**
     * 发送信息给指定用户
     * 
     * @param clientId
     * @param message
     * @return
     */
    public boolean sendMessageToUser(String fromName, String toName, String message) {
        javax.websocket.Session session = sessionMap.get(toName);
        System.out.println("sendMessageTo:" + session);
        if (!session.isOpen())
            return false;
        try {
            session.getBasicRemote().sendText(fromName + ":" + message);
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 广播给所有人
     * 
     * @param message
     */
    public static void sendMessageToAll(String fromName, String message) {
        Set<Map.Entry<String, Session>> set = sessionMap.entrySet();
        System.out.println("在线人数:" + set.size());
        for (Map.Entry<String, Session> i : set) {
            try {
                i.getValue().getBasicRemote().sendText(fromName + ":" + message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        sessionMap.remove(session.getId());
        Set<Map.Entry<String, Session>> set = sessionMap.entrySet();
        System.out.println("游客" + session.getId() + "退出");
        System.out.println("在线人数:" + set.size());
        sendMessageToAll("系统提示:", "游客" + session.getId() + "退出");
    }

    @OnError
    public void error(Session session, java.lang.Throwable throwable) {
        sessionMap.remove(session.getId());
        System.err.println("session " + session.getId() + " error:" + throwable);
    }

}

jsp页面导入js

 <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
 <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.min.js"></script>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8" import="java.util.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<%request.getSession().setAttribute("user", "shlly");%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <script src="http://cdn.sockjs.org/sockjs-0.3.min.js"></script>
    <script src="https://cdn.bootcss.com/stomp.js/2.3.3/stomp.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;
           var user="<%=request.getSession().getAttribute("user")%>";
            if ('WebSocket' in window) {
                websocket = new WebSocket("ws://127.0.0.1:8080/wsdemo/websocket");
            } else if ('MozWebSocket' in window) {
                websocket = new MozWebSocket("ws://wsdemo");
            } else {
                websocket = new SockJS("http://127.0.0.1:8080/wsdemo/websocket");
                stompClient = Stomp.over(socket);
                stompClient.connect({}, function(frame) {
                    setConnected(true);
                });
            }
            websocket.onopen = function (evnt) {
                $("#tou").html("链接服务器成功!")
            };
            websocket.onopen = function (evnt) {
                $("#tou").html("链接服务器成功!")
            };
            var stompClient = Stomp.over(websocket); 
            //当有消息时,会自动调用此方法
            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("{\"toname\":\"all\",\"message\":\""+message+"\,\"user\":\""+user+"\"}");
                } else {
                    alert('未与服务器链接.');
                }
            }

            //强制关闭浏览器断开连接
            window.onbeforeunload = function() {
                if (stompClient != null) {
                    stompClient.disconnect();
                }
            }
        });
    </script>

</head>
<body>

<%=request.getSession().getAttribute("user")%>
<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 -->
</body>

</html>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值