WebSocket初建聊天室

来源:互联网 发布:社交网络评论音轨 编辑:程序博客网 时间:2024/05/14 04:35

最近在新观css3与html5相关的内容时,发现一个不错的好东西WebSocket,以前只是用过Oracle内建包的UTL_TCP,对于直接用socket与第三方服务进行通讯,确实是一件让人比较爽的事情,一些新思路顿时开阔起来。WebSocket允许浏览器里直接调用socket与服务器进行通讯,同时服务器还能主动给浏览器端进行消息推送,确实进一步丰富了BS结构,至少在浏览器里的游戏、新业务的实现,都提供了一个不错的技术选择,但是新技术毕竟还只是起步阶段,还有很多需要不断完善。

下面通过一个聊天室的例子,来慢慢了解WebSocket吧,详细的注释说明参考代码。

运行环境:

1 tomcat 8 用户web服务器及websocket服务器(其实是一个服务器,主要是WebSocket的TCP握手连接协议依赖于http协义,详细的文章参考http://tomcat.apache.org/tomcat-8.0-doc/web-socket-howto.html)

2 Myeclips 10.7,主要是用于类的编写(回头tomcat 8对应的webapps直接改到路径WebRoot对应的路径,即<Context path="/html5" docBase="D:\forDBCl\Html5\WebRoot" reloadable="true"></Context>),该版本的myeclips不支持集成tomcat 8

以上环境最大的不方便是没有办法进行调试。

强烈推荐:Myclips2015,上面可以直接开搞。


2 相关的脚本代码

2.1 WebSocket服务端参考代码,消息处理核心类

package com.cn.ljb.html5;import java.io.IOException;import java.util.Set;import java.util.concurrent.CopyOnWriteArraySet;import java.util.concurrent.atomic.AtomicInteger;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.cn.ljb.util.CommonUtils;//后面的字符串决定了请建立websocket连接地址内容的一部分@ServerEndpoint(value = "/websocket/chat")public class WSChatServlet{    private static final String GUEST_PREFIX = "Guest";    private static final AtomicInteger connectionIds = new AtomicInteger(0);    private static final Set<WSChatServlet> connections =            new CopyOnWriteArraySet<WSChatServlet>();    private Session lsession;    private String connectFlag;    private String nickname = "defaultNick";    public WSChatServlet() {    connectFlag = GUEST_PREFIX + connectionIds.getAndIncrement();        System.out.println("-------WSChatServlet run construct function"+connectFlag);    }    @OnOpen    public void start(Session session) {    if(connections.contains(this))    System.out.println("session has exist in the Set,and Setsize="+connections.size());    else{    lsession = session;    connections.add(this);    }    System.out.println("-----------onOpen CurrentConnections="+connections.size()+",Flag="+connectFlag);        //String message = String.format("* %s %s", connectFlag, ".....加入聊天室......");        //broadcast(message);    }    @OnClose    public void end() {        if(connections.remove(this)){    System.out.println("-----------affter OnClose CurrentConnections="+connections.size());        broadcast("....我离开了聊天室...",this.nickname);        }    }    @OnMessage    public void incoming(String message) {        // Never trust the clientString filteredMessage = CommonUtils.filter(message.toString());System.out.println("----sendMessage="+filteredMessage);String data[] = filteredMessage.split("[|]");    if(data!=null && data.length>0){    this.nickname = data[0];    broadcast(data[1],this.nickname);    }    }    @OnError    public void onError(Throwable t) throws Throwable {        System.out.println("--------------Chat Error: " + t.toString());    }    /**     * @param type 1 连接消息  2 正式消息 3 离开消息     * @param msg 消息主体     * @param userName 消息发送人     */    private static void broadcast(String msg,String userName) {    String jsonData = String.format("[{\"username\":\"%s\",\"content\":\"%s\"}]", userName+" "+CommonUtils.getLongDateNow(1),msg);        for (WSChatServlet client : connections) {            try {                synchronized (client) {                    client.lsession.getBasicRemote().sendText(jsonData);                }            } catch (IOException e) {            System.out.println("Chat Error: Failed to send message to client");                connections.remove(client);                try {                    client.lsession.close();                } catch (IOException e1) {                    // Ignore                }                broadcast("......我离开了......",userName);            }        }    }        }

2.2 相关的工具辅助类,没有什么好讲的

package com.cn.ljb.util;import java.util.Calendar;import java.util.Date;public class CommonUtils {    public static String filter(String message) {        if (message == null)            return (null);        char content[] = new char[message.length()];        message.getChars(0, message.length(), content, 0);        StringBuilder result = new StringBuilder(content.length + 50);        for (int i = 0; i < content.length; i++) {            switch (content[i]) {            case '<':                result.append("<");                break;            case '>':                result.append(">");                break;            case '&':                result.append("&");                break;            case '"':                result.append(""");                break;            default:                result.append(content[i]);            }        }        return (result.toString());    }        public static String getLongDateNow(int dataType) {Calendar now = Calendar.getInstance();String dateString = null;now.setTime(new Date());switch(dataType){case 1:dateString = String.format("%04d-%02d-%02d %02d:%02d:%02d.%03d", now.get(Calendar.YEAR),now.get(Calendar.MONTH)+1,now.get(Calendar.DAY_OF_MONTH),now.get(Calendar.HOUR_OF_DAY),now.get(Calendar.MINUTE),now.get(Calendar.SECOND),now.get(Calendar.MILLISECOND));break;case 2:dateString = String.format("%04d-%02d-%02d", now.get(Calendar.YEAR),now.get(Calendar.MONTH)+1,now.get(Calendar.DAY_OF_MONTH));break;case 3:now.add(Calendar.DAY_OF_MONTH, -1);dateString = String.format("%04d-%02d-%02d", now.get(Calendar.YEAR),now.get(Calendar.MONTH)+1,now.get(Calendar.DAY_OF_MONTH));break;default:break;}return dateString;}}

3 前端页面代码及js代码(合到一起了)

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"><head><title>测试聊天程序基于WebSocket</title><style type="text/css">#console {border-radius:5px;    border: 1px solid #CCCCCC;    border-right-color: #999999;    border-bottom-color: #999999;    height: 300px;    overflow-y: scroll;    padding: 5px;    width: 100%;}#console p {padding: 0;margin: 0;}</style></head><body><div id="mainContent" style="margin:0 auto;height:300px;width:50%;text-align:left;"><div id="console-container" style="margin:0 auto;height:300px;width:100%;padding-bottom:10px;"><div id="console"></div></div><p><nav><input type="button" value="加入群聊" onclick="joinChat()"></nav></p><p><span>昵称:</span><input id="nickname" type="text" style="width:20%;" placeholder="输入昵称"><input type="text" style="width:80%;" placeholder="输入你的聊天内容,回车发送" id="chat" />  <input type="button" value="发送消息" onclick="sendMessage()"></p></div></body></html><script type="text/javascript">var ynickname=null;var Chat = {};Chat.socket = null;Chat.connect = (function(host) {    if ('WebSocket' in window) {        Chat.socket = new WebSocket(host);    } else if ('MozWebSocket' in window) {        Chat.socket = new MozWebSocket(host);    } else {        Console.log("<h2 style='color: #ff0000'>该浏览器不支持websocket技术,请使用chrome或firefox等其他浏览器!</h2>");        return;    }    Chat.socket.onopen = function () {    document.getElementById('chat').onkeydown = function(event) {            if (event.keyCode == 13) {               sendMessage();            }        };    Chat.socket.send(ynickname+"|我加入了聊天哦");        //Console.log("消息:"+document.getElementById("nickname").value+" connect server success");            };    Chat.socket.onclose = function () {        document.getElementById('chat').onkeydown = null;        //Console.log("消息:"+document.getElementById("nickname").value+" close connection from server");    };    Chat.socket.onmessage = function (message) {        Console.log(message.data);    };});Chat.initialize = function() {if(ynickname==null){var nkname = document.getElementById('nickname').value;    if(nkname==''){    alert("请先给自己取一个昵称,然后开始聊天呗!");    return;    } else {    ynickname = nkname;    }} else {document.getElementById('nickname').value = ynickname;}        if(Chat.socket==null)    if (window.location.protocol == 'http:') {        Chat.connect('ws://'+window.location.host+'/html5<strong>/websocket/chat</strong>');    } else {        Chat.connect('wss://'+window.location.host+'/html5<strong>/websocket/chat</strong>');    }        };Chat.sendConnMessage = (function(inputMsg) {if(inputMsg!='' || inputMsg!=null){var sendResult = Chat.socket.send(inputMsg);}});Chat.disConnect = (function() {    Chat.socket.onclose();});var Console = {};Console.log = (function(message) {var jsonData = eval(message);if(jsonData.length>0){    var console = document.getElementById('console');    var p = document.createElement('p');    p.style.wordWrap = 'break-word';    p.innerHTML = "<font color='blue'>"+jsonData[0].username+":</font><br>    "+jsonData[0].content;    console.appendChild(p);    while (console.childNodes.length > 25) {        console.removeChild(console.firstChild);    }    console.scrollTop = console.scrollHeight;    }});function joinChat(){Chat.initialize();}function sendMessage(){if(ynickname==null){var nkname = document.getElementById('nickname').value;    if(nkname==''){    alert("请先给自己取一个昵称,然后开始聊天呗!");    return;    } else {    ynickname = nkname;    }} else {document.getElementById('nickname').value = ynickname;}var message = document.getElementById('chat').value;    if (message != '') {        Chat.sendConnMessage(ynickname+"|"+message);        document.getElementById('chat').value = '';    }}function leaveChat(){Chat.disConnect();}</script>

最终的基本代码是全部在上面了!我们再来看一个效果截图,拿个拔号路由器配置一条转发,就能轻松跟好友们搭建临时聊天室了。


0 0
原创粉丝点击