首先建立一个html:<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>far</title>    <style>        #chatWindow{            font-family: 微软雅黑;            height:700px;            width:800px;            font-size:12px;/*字体大小*/            position: absolute;/*绝对定位*/            /*margin:auto;自动布局,容器居中*/            /*阴影效果*/            box-shadow: gray 0px 4px 5px;/*阴影:颜色*/

            display: none;/*开始不显示chatWindow这个div*/        }        #title{            height:40px;            line-height:40px;            /**/            /*背景渐变*/            background:-webkit-linear-gradient(left, #4B8CFE 0%,#ffffff 120%);            text-align: center;/*容器中的内容居中*/            color:white;/*字体颜色*/        }        #data{            height:400px;            border-top:1px solid gray;            border-bottom:1px solid gray;            overflow-y:auto;/*溢出部分显示滚动条*/            padding: 2px;        }        #util>a{            display: inline-block;            width: 30px;            height: 25px;            margin: 0 5px;        }        #util>a:hover{            background-color: gray;            border-radius: 4px;        }        #send{            height:180px;            padding: 5px;/*上下左右都和输入内容有点(5px)距离*/            outline: none;/*去掉边框*/            overflow-y:auto;/*溢出部分显示滚动条*/        }        #btns{            text-align: right;            padding-right: 10px;/*盒子的内容距离边框的距离,简称内距离*/        }        .btnSetting{/* .代表class*/            width:72px;            height:28px;            display: inline-block;/*转成行块标签*/            line-height: 28px;            border:1px solid gray;            font-size:12px;font-family:"微软雅黑";text-align: center;            border-radius: 3px;/*圆角*/            text-decoration: none;/*去除下划线*/            margin-right:10px;/*外间距,盒子与别的盒子的距离*/            vertical-align: 1px;/*垂直位置上的调整*/        }        .i1{            background:url("/images/1.jpg") no-repeat center;        }        .i2{            background: url("/images/2.jpg") no-repeat center;        }        .i3{            background: url("/images/3.jpg") no-repeat center;        }        .dataBox{            border-radius: 5px;            padding: 3px;            background-color: #66afe9;            color:black;            width:auto;/*内容不固定大小,多少内容就用多少空间,可换行*/            display: inline-block;            margin-left: 10px;        }        .fright{            float:right;            clear: both;            text-align: right;        }        .fleft{            float:left;            clear: both;        }        .dou{            clear:both;            text-align: center;            line-height: 30px;            border-radius: 5px;            background-color: #4B8CFE;        }        #closeBtn {            color: black; /*字体颜色*/        }        #closeBtn:hover{            background-color: #EFEFF0;        }        #sendBtn {            background-color: #4B8CFE;            color:white;/*字体颜色*/        }        #sendBtn:hover{            background-color: #47C8F8;        }    </style>    <link rel="stylesheet" href="/css/facebox.css">    <script src="js/jquery-2.1.1.min.js"></script>    <script src="js/jquery.qqFace.js"></script>    <script>        var ws;        //#:找到id为chatBtn的节点,绑定一个点击事件 $符号代表框架。        $(document).ready(function () {        $("#chatBtn").click(function () {            //找到nickName获取val值。            var nickName = $("#nickName").val();            if ($.trim(nickName) == "") {//trim()函数的作用是去掉左右两边的空格。                alert("请输入昵称!");                return;//结束该函数            }            var url = "ws://" + window.location.hostname + ":8080/chatHandle/" + nickName;            //var url1="ws://"+window.location.hostname+":8080/chatHandle/"+fang;            //document.write(url+url1);            ws = new WebSocket(url);            //当后台服务器发了消息的时候,获取到后台消息            ws.onmessage=function (chatBtn) {                var index=chatBtn.data.indexOf("\0");                if(index>=0) {                    dou();                }                $("#data").scrollTop(520);                $("#data").append(chatBtn.data+"<br>");            }            $("#join").hide();            $("#chatWindow").show();            /*            关闭按钮            */            $("#closeBtn").click(function () {                ws.close();//关闭客户端与服务端的连接                $("#join").show();                $("#chatWindow").hide();            })            /*            发送按钮            */            $("#sendBtn").click(function () {                var val=$("#send").html();                //清空                $("#send").html("");                //聚焦                $("#send").focus();                //获取并发送                ws.send(val);            })            //添加快捷键            $("#send").keydown(function (event) {                if(event.altKey && event.keyCode==67){                    $("#closeBtn").click();//模拟手动点击,代码点击;                }                if((event.altKey && event.keyCode==83)|| event.keyCode==13){                    $("#sendBtn").click();//模拟手动点击发送按钮,代码点击;                }            })        })            var reader=new FileReader();            var myFile=document.getElementById("myFile");            myFile.onchange=function () {                var chooseFile=myFile.files[0];                reader.readAsDataURL(chooseFile);            }            reader.onload=function () {                var obj=document.createElement("img");                obj.src=reader.result;                $("#send").append(obj);            }            $("#myFile").hide();            $(".i1").click(function () {                $("#myFile").click();            })            $(".i2").qqFace({                id:'facebox',                assign:'send',                path:'arclist/'            })            /*拖拽部分*/            var title=document.getElementById("title");            var pyx,pyy;            title.ondragstart=function (e) {                pyx=e.offsetX;                pyy=e.offsetY;            }            title.ondrag=function (e) {                var x=e.pageX;                var y=e.pageY;                if(x==0&&y==0)   return;                $("#chatWindow").css("left",x-pyx);                $("#chatWindow").css("top",y-pyy);            }            $(".i3").click(function () {                ws.send("\0");            })            function dou() {                var initx=$("#chatWindow").offset().left;                var inity=$("#chatWindow").offset().top;                for(var i=0;i<=10;i++){                    $("#chatWindow").animate({"left":initx-10,"top":inity-10},10);                    $("#chatWindow").animate({"left":initx,"top":inity},10);                    $("#chatWindow").animate({"left":initx+10,"top":inity+10},10);                    $("#chatWindow").animate({"left":initx,"top":inity},10);                }            }        })    </script></head><body><div id="join"><!-----div可以看成一个盒子,容器。固定页面布局。CSS(放head里面)相当对html的"化妆";------->    <input id="nickName" type="text"><br>    <input id="chatBtn" type="button" value="加入聊天室"><br></div><div id="chatWindow">    <div id="title" draggable="true">far away</div>    <div id="data"></div><!----聊天内容------->    <div id="util"><!--工具区域-->    <input type="file" id="myFile">    <a class="i1" href="javascript:;"></a>    <a class="i2" href="javascript:;"></a>    <a class="i3" href="javascript:;"></a></div>    <div id="send" contenteditable="true"></div><!----要发送内容------->    <div id="btns"><!------发送和关闭按钮-------->        <a id="closeBtn" class="btnSetting" href="javascript:;">关闭(<u>C</u>)</a>        <a id="sendBtn" class="btnSetting" href="javascript:;">发送(<u>S</u>)</a>    </div></div></body></html>

后台控制代码:
package com.seecon.Chat.handle;

import javax.websocket.OnClose;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.ServerEndpoint;import javax.websocket.server.PathParam;import java.util.ArrayList;import java.util.Calendar;import java.util.List;

@ServerEndpoint("/chatHandle/{nickName}")public class ChatHandle {    //创建一个静态的“袋子”(跟对象无关),用来装所有的session,也就是所有用户的会话;    private static List<Session> users=new ArrayList<Session>();//static可以共享。    public static synchronized void add(Session session){//静态方法不依赖对象        users.add(session);    }    public synchronized  static void remove(Session session){        users.remove(session);    }    private void sendAll(String message){        for (Session user : users) {            user.getAsyncRemote().sendText(message);        }    }    private String nickName;/*当前会话的昵称*/    @OnOpen    public void connect(Session session,@PathParam("nickName") String nickName) throws Exception {        System.out.println(nickName + "连接上了后台服务器程序" + session);        add(session);        sendAll("<div class='fleft'>-----欢迎[" + nickName + "]------加入聊天室  "+"当前聊天室人数:"+users.size()+"</div>");        this.nickName=nickName;    }    @OnClose    public void exit(Session session,@PathParam("nickName") String nickName) throws Exception{        remove(session);        sendAll("<div class='fright'>----[" + nickName + "]------退出聊天室"+"当前聊天室人数:"+users.size()+"</div>");    }    @OnMessage    public void receiveMessage(Session session,String message) throws Exception{        Calendar c=Calendar.getInstance();        int hour=c.get(Calendar.HOUR_OF_DAY);        String hourStr=hour>=10?hour+"":"0"+hour;        int minute=c.get(Calendar.MINUTE);        String minuteStr=minute>=10?minute+"":"0"+minute;        int second=c.get(Calendar.SECOND);        String secondStr=second>=10?second+"":"0"+second;        String fullTime=hourStr+":"+minuteStr+":"+secondStr;        //构建message        if(message.equals("\0")){            message="<div class='dou'>"+nickName+"给您发送了一个窗口抖动</div>";            String str="&nbsp;&nbsp;"+fullTime+"<br>"+message;            sendAll("\0"+str);        }else {            message = "<div class='dataBox'>" + message + "</div>";            String str = nickName + "&nbsp&nbsp" + fullTime + "<br>" + message;            sendAllMessage(str, session);        }    }    private void sendAllMessage(String message,Session session){        //把Message的数据通知给所有会话        for(Session user:users){            if(user==session){                user.getAsyncRemote().sendText("<div class='fright'>"+message+"</div>");            }            else{                user.getAsyncRemote().sendText("<div class='fleft'>"+message+"</div>");

            }        }    }

}

类似QQ的聊天工程的更多相关文章

  1. java网络编程(三):一个类似QQ的聊天程序

    客户端: package QQ; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import ...

  2. AndroidRichText 让Textview轻松的支持富文本(图像ImageSpan、点击效果等等类似QQ微信聊天)

    代码地址:https://github.com/Luction/AndroidRichText AndroidRichText帮助实现像QQ,微信一样的,一个TextView里既有文字又有表情又有图片 ...

  3. 实现类似QQ对话聊天功能脚本

    var skin : GUISkin; var showChat = false;private var inputField = "";private var display = ...

  4. [C# 网络编程系列]专题九:实现类似QQ的即时通信程序

    转自:http://www.cnblogs.com/zhili/archive/2012/09/23/2666987.html 引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例 ...

  5. 基于Qt的类QQ气泡聊天的界面开发

    近期在写IM 聊天界面,想设计出一个类似QQ气泡聊天的样式 使用了几种办法 1:使用Qt以下的QListview来实现QQ类似效果.差强人意 2:使用QWebview载入html css样式来完毕.发 ...

  6. 详解C# 网络编程系列:实现类似QQ的即时通信程序

    https://www.jb51.net/article/101289.htm 引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net ...

  7. 转:【专题九】实现类似QQ的即时通信程序

    引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net类库去实现它们的.为了让大家更好的理解我们平常中常见的软件QQ的工作原理,所以在 ...

  8. 专题九:实现类似QQ的即时通信程序

    引言: 前面专题中介绍了UDP.TCP和P2P编程,并且通过一些小的示例来让大家更好的理解它们的工作原理以及怎样.Net类库去实现它们的.为了让大家更好的理解我们平常中常见的软件QQ的工作原理,所以在 ...

  9. MVC实现类似QQ的网页聊天功能-ajax(下)

    此篇文章主要是对MVC实现类似QQ的网页聊天功能(上)的部分代码的解释. 首先说一下显示框的滚动条置底的问题: 结构很简单一个大的div(高度一定.overflow:auto)包含着两个小的div第一 ...

随机推荐

  1. [Java反射基础一]Class类的使用

    任何一个类都是Class类的实例对象,这个实例对象有三种表示方式 第一种表示方式(任何一个类都有一个隐含的静态成员变量class): Class c1 = Foo.class; 第二种表示方式(已知该 ...

  2. 深入理解jQuery插件开发总结(三)

    容器:一个即时执行函数 根本上来说,每个插件的代码是被包含在一个即时执行的函数当中,如下: (function(arg1, arg2) { // 代码 })(arg1, arg2); 即时执行函数,顾 ...

  3. IntelliJ IDEA16 热部署,解决每次修改java文件就得重启tomcat的问题

    这样就可以了....

  4. JS里的居民们6-数组排序

    编码 var arr = [43, 54, 4, -4, 84, 100, 58, 27, 140]; 将上面数组分别按从大到小以及从小到大进行排序后在console中输出 var arr = ['a ...

  5. python 中 \n 和转义r的作用和\r的实际应用

    我们先看看这张转义字符图: 1. 知识储备 \r 表示将光标的位置回退到本行的开头位置 \b 表示将光标的位置回退一位 在 python 语言中, 使用 print 打印输出时,默认是会进行换行的.如 ...

  6. CentOS下调整home和根分区大小

    由于我们有时候没法预估或者说错误的盘符分区的时候,常常会导致我们后面的操作出现极大的不方便,这里我就记录下一个错误分区后对home和根分区存储空间大小调整的整个过程! ①查看我们现有机器的分区状况 c ...

  7. 按键精灵Q语言基础

    一.数据类型1.1数据类型可以表示一切的类型variant逻辑类型:boolean (true,false)数学类型: 整数:byte(0-255),integer(-32768-32767),lon ...

  8. 自学git心得-1

    Github作为目前世界上最先进的分布式版本控制系统,是软工工作者管理工程代码的不二选择,笔者也是因时所需,自学了基本的git操作,在此回顾一下也作为分享. 推荐学习资源:https://www.li ...

  9. HDFS元数据管理机制

    元数据管理概述 HDFS元数据,按类型分,主要包括以下几个部分: 1.文件.目录自身的属性信息,例如文件名,目录名,修改信息等. 2.文件记录的信息的存储相关的信息,例如存储块信息,分块情况,副本个数 ...

  10. Linux系统学习之系统启动的5个过程

    Linux 系统启动过程 Linux系统的启动过程可以分为5个阶段: 1. 内核引导 当计算机打开电源后,首先是BIOS开机自检,按照BIOS中设置的启动设备(通常是硬盘)来启动.操作系统接管硬件以后 ...