javaweb学习路之三--websocket多人在线聊天

在之前的项目基础上,加入了一个聊天室的功能,为了界面好看 引入了AmazeUI和umeditor最终效果图如下:

源码在 https://github.com/Zering/MyWeb 目前练习都在这个上面做

如果导入maven项目出现 Cannot change version of project facet Dynamic Web Module to 3.0.之类的错误时,可以参考http://www.cnblogs.com/zhanghj405/p/5579627.html

 

进入正题

jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport"
    content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>We Chat</title>
<!-- Set render engine for 360 browser -->
<meta name="renderer" content="webkit">
<!-- No Baidu Siteapp-->
<meta http-equiv="Cache-Control" content="no-siteapp" />
<link rel="alternate icon" href="../assets/i/favicon.ico">
<link rel="stylesheet" href="../assets/css/amazeui.min.css">
<link rel="stylesheet" href="../assets/css/app.css">
<!-- umeditor css -->
<link href="../umeditor/themes/default/css/umeditor.css"
    rel="stylesheet">
<style>
.title {
    text-align: center;
}

.chat-content-container {
    height: 29rem;
    overflow-y: scroll;
    border: 1px solid silver;
}
</style>
</head>
<body>
    <!-- title start -->
    <div class="title">
        <div class="am-g am-g-fixed">
            <div class="am-u-sm-12">
                <h1 class="am-text-primary">We Chat</h1>
            </div>
        </div>
    </div>
    <!-- title end -->
    <!-- chat content start -->
    <div class="chat-content">
        <div class="am-g am-g-fixed chat-content-container">
            <div class="am-u-sm-12">
                <ul id="message-list" class="am-comments-list am-comments-list-flip"></ul>
            </div>
        </div>
    </div>
    <!-- chat content start -->
    <!-- message input start -->
    <div class="message-input am-margin-top">
        <div class="am-g am-g-fixed">
            <div class="am-u-sm-12">
                <form class="am-form">
                    <div class="am-form-group">
                        <script type="text/plain" id="myEditor"
                            style="width: 100%; height: 8rem;"></script>
                    </div>
                </form>
            </div>
        </div>
        <div class="am-g am-g-fixed am-margin-top">
            <div class="am-u-sm-6">
                <div id="message-input-nickname"
                    class="am-input-group am-input-group-primary">
                    <span class="am-input-group-label"><i class="am-icon-user"></i></span>
                    <input id="nickname" value="${username}" type="text"
                        class="am-form-field" disabled />
                </div>
            </div>
            <div class="am-u-sm-6">
                <button id="send" type="button" class="am-btn am-btn-primary">
                    <i class="am-icon-send"></i> Send
                </button>
            </div>
        </div>
    </div>
    <!-- message input end -->
    <!--[if (gte IE 9)|!(IE)]><!-->
    <script src="../assets/js/jquery.min.js"></script>
    <!--<![endif]-->
    <!--[if lte IE 8 ]>
  <script src="http://libs.baidu.com/jquery/1.11.1/jquery.min.js"></script>
  <![endif]-->
    <!-- umeditor js -->
    <script charset="utf-8" src="../umeditor/umeditor.config.js"></script>
    <script charset="utf-8" src="../umeditor/umeditor.min.js"></script>
    <script src="../umeditor/lang/zh-cn/zh-cn.js"></script>
    <script>
        $(function() {
            // 初始化消息输入框
            var um = UM.getEditor('myEditor');
            // 使昵称框获取焦点
            $('#nickname')[0].focus();

            var socket = null;
            function parseObj(strData) {//转换对象
                return (new Function("return " + strData))();
            }
            ;
            //创建socket对象
            socket = new WebSocket("ws://" + window.location.host
                    + "/${pageContext.request.contextPath}/wechat");
            //连接创建后调用
            socket.onopen = function() {
                $("#message-list").append($('#nickname').val() + "进入聊天室<br/>");
            };
            //接收到服务器消息后调用
            socket.onmessage = function(message) {
                var message = parseObj(message.data);
                var messageItem = '<li class="am-comment '
                        + (message.isSelf ? 'am-comment-flip' : 'am-comment')
                        + '">'
                        + '<a href="javascript:void(0)" ><img src="../assets/images/'
                        + (message.isSelf ? 'self.png' : 'others.jpg')
                        + '" alt="" class="am-comment-avatar" width="48" height="48"/></a>'
                        + '<div class="am-comment-main"><header class="am-comment-hd"><div class="am-comment-meta">'
                        + '<a href="javascript:void(0)" class="am-comment-author">'
                        + message.nickname + '</a> <time>' + message.date
                        + '</time></div></header>'
                        + '<div class="am-comment-bd">' + message.content
                        + '</div></div></li>';
                $(messageItem).appendTo('#message-list');
                // 把滚动条滚动到底部
                $(".chat-content-container").scrollTop(
                        $(".chat-content-container")[0].scrollHeight);
            };
            //关闭连接的时候调用
            socket.onclose = function() {
                $("#message-list").append($('#nickname').val() + "退出聊天室<br/>");
            };
            //出错时调用
            socket.onerror = function() {
                alert("error");
            };
            $("#send").click(function() {
                var nickname = $('#nickname').val();
                // 发送消息
                socket.send(JSON.stringify({
                    content : um.getContent(),
                    nickname : nickname
                }));
                // 清空消息输入框
                um.setContent('');
                // 消息输入框获取焦点
                um.focus();
            });

        });
    </script>
</body>
</html>

后台socket

package com.app.websocket;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Hashtable;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.websocket.CloseReason;
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 com.alibaba.fastjson.JSON;

import net.sf.json.JSONObject;
//注意此访问地址格式如:"ws://"+ window.location.host+"/${pageContext.request.contextPath}/wechat"是ws开头的,而不是以http:开头的.
@ServerEndpoint(value = "/wechat")
public class Socket {

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm");    // 日期格式化
    
    private Logger logger = Logger.getLogger(this.getClass().getName());

    static Map<String,Session> sessionMap = new Hashtable<String,Session>();
    
    @OnOpen
    public void onOpen(Session session) {
        sessionMap.put(session.getId(), session);
    }

//    @OnMessage
//    public void onMessage(String unscrambledWord, Session session) {
//        broadcastAll("message",unscrambledWord);
//    }
    
    @OnMessage
    public void getMessage(String message, Session session) {
        
        Set<Map.Entry<String,Session>> set = sessionMap.entrySet();
        // 把客户端的消息解析为JSON对象
        JSONObject jsonObject = JSONObject.fromObject(message);
        // 在消息中添加发送日期
        jsonObject.put("date", DATE_FORMAT.format(new Date()));
//        // 把消息发送给所有连接的会话
//        for (Session openSession : session.getOpenSessions()) {
//          // 添加本条消息是否为当前会话本身发的标志
//          jsonObject.put("isSelf", openSession.equals(session));
//          // 发送JSON格式的消息
//          openSession.getAsyncRemote().sendText(jsonObject.toString());
//        }
        for(Map.Entry<String,Session> i: set){
            try {
                jsonObject.put("isSelf", i.getValue().equals(session));
                i.getValue().getBasicRemote().sendText(JSON.toJSONString(jsonObject));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
      }
//    /**
//     * 广播给所有人
//     * @param message
//     */
//    public static void broadcastAll(String type,String message){
//        Set<Map.Entry<String,Session>> set = sessionMap.entrySet();
//        for(Map.Entry<String,Session> i: set){
//            try {
//                i.getValue().getBasicRemote().sendText("{type:'"+type+"',text:'"+message+"'}");
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
//        }
//    }

    @OnClose
    public void onClose(Session session, CloseReason closeReason) {
        sessionMap.remove(session.getId());
        logger.info(String.format("Session %s closed because of %s", session.getId(), closeReason));
    }
    
    @OnError
    public void error(Session session, java.lang.Throwable throwable){
        sessionMap.remove(session.getId());
        System.err.println("session "+session.getId()+" error:"+throwable);
    }
}

@onmessage里面的改写是为了配合umeditor里面 可以发表情,图片,文件等一系列功能

 

posted on 2016-06-13 13:54  执念saying  阅读(4740)  评论(4编辑  收藏  举报

导航