zoukankan      html  css  js  c++  java
  • websocket 在线聊天

    客户端:jsp页面部分

    <%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>
    <%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
    <%@ taglib uri="http://www.springframework.org/tags" prefix="s" %>
    <c:set var="cjq" value="${pageContext.request.contextPath}" />

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta charset="utf-8" />
    <title>欢迎回来,${user.username}</title>

    <meta name="description" content="overview &amp; stats" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" />
    <link rel="stylesheet" type="text/css" href="${cjq}/static/assets/jdigiclock/css/jquery.jdigiclock.css" />
    <link rel="stylesheet" href="${cjq}/static/assets/css/bootstrap.min.css" />
    <link charset="utf-8" type="text/css" rel="stylesheet" href="https://img.tenpay.com/v2/res_mch_open/component/date/date.css" />

    </head>

    <body class="no-skin">
    <jsp:include page="/WEB-INF/jsp/common/header.jsp" />

    <div class="main-container ace-save-state" id="main-container">


    <div id="sidebar" class="sidebar responsive ace-save-state compact">

    <jsp:include page="/WEB-INF/jsp/common/left.jsp" />

    </div>

    <div class="main-content">
    <div class="main-content-inner">
    <div class="breadcrumbs ace-save-state" id="breadcrumbs">
    <ul class="breadcrumb">
    <li><i class="ace-icon fa fa-home home-icon"></i> <a href="${cjq}/main">首页</a>
    </li>
    <li class="active">聊天室</li>
    </ul>
    </div>
    <div class="page-content">
    <div class="page-header">
    <h1>
    不夜城=>${time}
    <small>
    <i class="ace-icon fa fa-angle-double-right"></i>
    BBS &amp; cjq
    </small>
    </h1>

    </div>

    <div class="alert alert-info">
    <i class="ace-icon fa fa-hand-o-right"></i>
    说话周到比雄辩好,措词适当比恭维好------培根
    <button class="close" data-dismiss="alert">
    <i class="ace-icon fa fa-times"></i>
    </button>
    </div>

    <div class="widget-toolbar no-border " style="line-height: 77px;float:left">
    <input type="text" id="text" style="line-height:22px;500px"/>
    <a class="btn btn-sm btn-primary"
    onclick="send()">发送消息</a>
    </div>
    <div class="widget-toolbar no-border " style="line-height: 77px;">
    <a class="btn btn-sm btn-primary"
    onclick="closeWebSocket()">关闭连接</a>
    <a class="btn btn-sm btn-primary"
    onclick="createWebSocket()">重新连接</a>
    </div>


    </div>

    </div>
    <div class="row">

    <textarea rows="20" cols="165" id="message" style="float:left;margin-left:30px" readonly="true">

    </textarea>

    </div>
    <!-- /.page-content -->
    </div>
    </div>
    <!-- /.main-content -->

    <jsp:include page="/WEB-INF/jsp/common/footer.jsp" />
    <script src="${cjq }/static/assets/js/bootstrap.min.js"></script>
    <script type="text/javascript">
    var websocket = null;
    //连接初始化聊天室
    createWebSocket();


    //监听窗口关闭事件,当窗口关闭时,主动去关闭websocket连接,防止连接还没断开就关闭窗口,server端会抛异常。
    window.onbeforeunload = function () {
    closeWebSocket();
    }
    //将消息显示在网页上 并清空输入框
    function setMessageInnerHTML(innerHTML) {
    $("#text").val("");
    var str = $("#message").val(); //先获取原有的值
    $("#message").val(str + innerHTML+" "); //拼接新值
    }
    //关闭WebSocket连接
    function closeWebSocket() {
    websocket.close();
    //layer.msg("您已退出聊天室,将无法发送消息......");
    }
    //打开WebSocket连接
    function createWebSocket(){
    //判断当前浏览器是否支持WebSocket tomcat7不支持
    if ('WebSocket' in window) {
    websocket = new WebSocket("ws://localhost:8080/TestPro/websocket");
    //layer.msg("连接成功......");
    }
    else {
    alert('当前浏览器 Not support websocket');
    }

    //连接发生错误的回调方法
    websocket.onerror = function () {
    setMessageInnerHTML("WebSocket连接发生错误");
    };
    //连接成功建立的回调方法
    websocket.onopen = function () {
    setMessageInnerHTML("WebSocket连接成功");
    }
    //接收到消息的回调方法
    websocket.onmessage = function (event) {
    setMessageInnerHTML(event.data);
    }
    //连接关闭的回调方法
    websocket.onclose = function () {
    setMessageInnerHTML("WebSocket连接关闭");
    }
    }
    //发送消息
    function send() {
    var message = $("#text").val();
    websocket.send(message);
    }
    </script>


    </body>
    </html>

    -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    服务器端  jar包略

    package cn.mybatis.Api;
    import java.io.IOException;
    import java.util.Date;
    import java.util.concurrent.CopyOnWriteArraySet;


    import javax.servlet.http.HttpSession;
    import javax.websocket.*;
    import javax.websocket.server.ServerEndpoint;

    import cn.mybatis.Model.Chat;
    import cn.mybatis.Model.User;
    import cn.mybatis.Util.GetHttpSessionConfigurator;


    /**
    * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,
    * 注解的值将被用于监听用户连接的终端访问URL地址,客户端可以通过这个URL来连接到WebSocket服务器端
    */
    @ServerEndpoint(value="/websocket",configurator=GetHttpSessionConfigurator.class)
    public class SendWebSocket {
    //静态变量,用来记录当前在线连接数。应该把它设计成线程安全的。
    private static int onlineCount ;
    //concurrent包的线程安全Set,用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话,可以使用Map来存放,其中Key可以为用户标识
    private static CopyOnWriteArraySet<SendWebSocket> webSocketSet = new CopyOnWriteArraySet<SendWebSocket>();
    //与某个客户端的连接会话,需要通过它来给客户端发送数据
    private Session session;
    //HttpSession
    private HttpSession httpSession;
    /**
    * 连接建立成功调用的方法
    * @param session 可选的参数。session为与某个客户端的连接会话,需要通过它来给客户端发送数据
    * @param request
    */
    @OnOpen
    public void onOpen(Session session,EndpointConfig config){
    this.session = session;
    this.httpSession= (HttpSession) config.getUserProperties().get(HttpSession.class.getName());
    webSocketSet.add(this); //加入set中
    addOnlineCount(); //在线数加
    String message="有新连接加入!当前聊天室在线人数为" + getOnlineCount();
    System.out.println(message);
    onMessage(message, session);
    }
    /**
    * 连接关闭调用的方法
    */
    @OnClose
    public void onClose(){
    webSocketSet.remove(this); //从set中删除
    subOnlineCount(); //在线数减
    String message="有一连接关闭!当前聊天室在线人数为" + getOnlineCount();
    System.out.println(message);
    onMessage(message, session);
    }
    /**
    * 收到客户端消息后调用的方法
    * @param message 客户端发送过来的消息
    * @param session 可选的参数
    */
    @OnMessage
    public void onMessage(String message, Session session) {
    System.out.println("来自客户端的消息:" + message);
    //读取session中的用户
    User user = (User) httpSession.getAttribute("user");
    //数据格式
    Chat chat =new Chat();
    chat.setChatContent(message);
    chat.setChatTime(new Date());
    chat.setCoordinationId(session.getId());
    chat.setName(user.getUsername());
    chat.setUserid(user.getId());
    chat.setIp("ip");
    //群发消息
    for(SendWebSocket item: webSocketSet){
    try {
    item.sendMessage(chat);
    } catch (IOException e) {
    e.printStackTrace();
    continue;
    }
    }
    }
    /**
    * 发生错误时调用
    * @param session
    * @param error
    */
    @OnError
    public void onError(Session session, Throwable error){
    System.out.println("发生错误");
    error.printStackTrace();
    }
    /**
    * 这个方法与上面几个方法不一样。没有用注解,是根据自己需要添加的方法。
    * @param message
    * @throws IOException
    */
    public void sendMessage(Object chat) throws IOException{
    this.session.getBasicRemote().sendText(chat.toString());
    //this.session.getAsyncRemote().sendText(message);
    }
    public static synchronized int getOnlineCount() {
    return onlineCount;
    }
    public static synchronized void addOnlineCount() {
    SendWebSocket.onlineCount++;
    }
    public static synchronized void subOnlineCount() {
    SendWebSocket.onlineCount--;
    }
    }

    --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    websocket获取httpSession工具类

    package cn.mybatis.Util;

    import javax.servlet.http.HttpSession;
    import javax.websocket.HandshakeResponse;
    import javax.websocket.server.HandshakeRequest;
    import javax.websocket.server.ServerEndpointConfig;
    import javax.websocket.server.ServerEndpointConfig.Configurator;

    public class GetHttpSessionConfigurator extends Configurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig sec,
    HandshakeRequest request, HandshakeResponse response) { // TODO Auto-generated method stub
    HttpSession httpSession=(HttpSession) request.getHttpSession();
    sec.getUserProperties().put(HttpSession.class.getName(),httpSession);
    }

    }

    --------------------------------------------------------------------------------------------------------------------------

    注:tomcat7下运行websocket会报错,显示连接不成功,更换tomcat8之后问题解决,tomcat版本问题(坑)

    Hpptsession设置为全局变量即可  

    当能力支撑不了野心时,就该静下心来学习!
  • 相关阅读:
    JS刷新当前页面的几种方法总结
    C#实现,C++实现,JS实现 阿拉伯数字金额转换为中文大写金额
    SQL server 生成数据字典
    jquery操作复选框(checkbox)的一些小技巧总结
    HTML中的几种空格
    C#几个经常用到的字符串截取
    关于百度地图API和jqGrid踩到的坑
    SQL常见问题积累
    JS实用小函数 数据是否合法或存在 获取当前日期时间
    vs2010 学习Silverlight学习笔记(13):数据与通信之WCF
  • 原文地址:https://www.cnblogs.com/1234cjq/p/7943450.html
Copyright © 2011-2022 走看看