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‘)
                        + ‘"  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里面 可以发表情,图片,文件等一系列功能

时间: 2024-11-13 00:46:16

javaweb学习路之三--websocket多人在线聊天的相关文章

基于Java NIO的多人在线聊天工具源码实现(登录,单聊,群聊)

近来在学习Java NIO网络开发知识,写了一个基于Java NIO的多人在线聊天工具练练手.源码公开在Coding上: https://coding.net/u/hust_wsh/p/MyChat/git ,开发环境是Ubuntu14.04+Eclipse Mars+JDK1.8. 要想编写一个基于Java NIO的多人在线聊天工具,我总结需要以下几方面的地址:客户端服务器模型,Java NIO中的Selector,SocketChannel,ByteBuffer,Collections以及序

javaweb学习路之四--cxf发布Webservice

背景:maven构建的springMvc+mybatis框架 源码--->https://github.com/Zering/MyWeb 步骤:(本步骤是自己在实际探索过程中的步骤,我的思路是先简单粗暴的写出方法,报错了再根据错误来解决问题) 第一步:直接写出了接口和实现类 示例接口代码 package com.app.service; import javax.jws.WebService; import javax.jws.soap.SOAPBinding; import javax.jws

JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 包含https 非对称秘钥 NB

JavaWeb学习总结(三)--Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下: 范例:将JavaWebDemoProject这个JavaWeb应用打包成war包 执行完之后,就可以得到一个文件,平时开发完JavaWeb应用后,一般都会将JavaWeb应用打包成一个war包,然后将这个war包放到Tomcat服务器的webapps目录下,当Tomcat服务器启动时,就会自动

JAVAWeb学习总结(3)

JavaWeb学习总结(三)——Tomcat服务器学习和使用(二) 一.打包JavaWeb应用 在Java中,使用"jar"命令来对将JavaWeb应用打包成一个War包,jar命令的用法如下: 范例:将JavaWebDemoProject这个JavaWeb应用打包成war包 执行完之后,就可以得到一个文件,平时开发完JavaWeb应用后,一般都会将JavaWeb应用打包成一个war包,然后将这个war包放到Tomcat服务器的webapps目录下,当Tomcat服务器启动时,就会自动

马哥Linux学习笔记之三——加密

1.明文传输 ftp,http,smtp,telnet 2.机密性:plaintext-->转换规则-->ciphertext ciphertext-->转换规则-->plaintext 完整性:单项加密算法,提取数据特征码.输入一样,输出必然一样:雪崩效应,输入的微小改变,将会引起结果的巨大改变:无论原始数据是多少,结果大小都是相同的:不可逆,无法根据特征码还原原来的数据. 3.密钥 4.对称加密:有加密算法,有密钥 5.密钥交换算法 IKE(Internet Key Excha

javaWeb学习总结(8)- jsp指令(3)

一.JSP指令简介 一.JSP指令简介 JSP指令(directive)是为JSP引擎而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分. 在JSP 2.0规范中共定义了三个指令: page指令 Include指令 taglib指令 JSP指令的基本语法格式:<%@ 指令 属性名="值" %> 例如: 1 <%@ page contentType="text/html;charset=gb2312"%> 如果

[多线程通信程序]C++基于Socket的一款多人在线通信程序

废话不多说,先上图. 进入正题:最近闲着无聊,想起来在初二时用VB写的一个局域网多人聊天室.当时用的是Winsock,然后写出来给同学上信息课用,其实也没啥用啊. 今天下午突发奇想,打算用C++实现这一功能.去百度了一下相关资料,才发现C++的socket是真的麻烦......(或许是我太菜了)于是于是于是,我很认真地开始学习(Copy).找了好久都没找到符合我意思的模板,而且突然发现如果要多人同时在线聊天的话,好像还要多线程来着,,???,,.于是我开始很认真的学习(别说了,是真的开始学习).

tornado+websocket+mongodb实现在线视屏文字聊天

最近学了tornado和mongo,所以结合websocket 实现一个聊天功能,从而加深一下相关知识点的印象 1.websocket概览 webscoket是一种全双工通信模式的协议,客户端连接服务端先通过tcp,http转为webscoket协议后,客户端和服务端都可以主动推送消息给另一端,这也是和http协议(服务端只能被动接收消息,无法主动推送消息给客户端)最大的区别. 2.tornado概览 tornado是一种异步网络库的python web框架,最初在 FriendFeed上开发,

SpringBoot+Vue+WebSocket 实现在线聊天

一.前言 本文将基于 SpringBoot + Vue + WebSocket 实现一个简单的在线聊天功能 页面如下: 在线体验地址:http://www.zhengqingya.com:8101 二.SpringBoot + Vue + WebSocket 实现在线聊天 1.引入websocket依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-bo