想学学html5的开发。就做个websocket的聊天室程序。其实都很简单,把协议用对就好。
具体的websocket的握手程序和解码编码都可以参照下面的链接
http://www.cnblogs.com/pctzhang/archive/2012/02/19/2358496.html
websocket的代码就简单得不想写了
下面是主要的java代码基于mina。如果有兴趣的话就下整个工程自己玩玩吧
package websocket;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* @author amu
*
*/
public class WebSocketIoHandler extends IoHandlerAdapter {
public static final String INDEX_KEY = WebSocketIoHandler.class.getName() + ".INDEX";
private static Logger LOGGER = LoggerFactory.getLogger(WebSocketIoHandler.class);
Map<Long, IoSession> ioSessionMap = new HashMap<Long, IoSession>();
public void messageReceived(IoSession session, Object message) throws Exception {
IoBuffer buffer = (IoBuffer)message;
byte[] b = new byte[buffer.limit()];
buffer.get(b);
Long sid = session.getId();
if (!ioSessionMap.containsKey(sid)) {
LOGGER.info("user '{}',has been created" + sid);
ioSessionMap.put(sid, session);
String m = new String(buffer.array());
String sss = getSecWebSocketAccept(m);
buffer.clear();
buffer.put(sss.getBytes("utf-8"));
buffer.flip();
session.write(buffer);
buffer.free();
} else {
String m = decode(b);
LOGGER.info("from client is :" + m);
buffer.clear();
byte[] bb = encode(m);
buffer.put(bb);
buffer.flip();
synchronized (ioSessionMap) {
Collection<IoSession> ioSessionSet = ioSessionMap.values();
for (IoSession is : ioSessionSet) {
if (is.isConnected()) {
System.out.println("response message to " + is);
is.write(buffer.duplicate());
}
}
}
buffer.free();
}
}
@Override
public void sessionOpened(IoSession session) throws Exception {
session.setAttribute(INDEX_KEY, 0);
}
@Override
public void sessionIdle( IoSession session, IdleStatus status ) throws Exception {
System.out.println( "IDLE " + session.getIdleCount( status ));
}
public static String getSecWebSocketAccept(String key) {
String secKey = getSecWebSocketKey(key);
String guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
secKey += guid;
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(secKey.getBytes("iso-8859-1"), 0, secKey.length());
byte[] sha1Hash = md.digest();
secKey = base64Encode(sha1Hash);
} catch (Exception e) {
e.printStackTrace();
}
String rtn = "HTTP/1.1 101 Switching Protocols\r\nUpgrade: websocket\r\nConnection: Upgrade\r\nSec-WebSocket-Accept: "
+ secKey + "\r\n\r\n";
return rtn;
}
public static String getSecWebSocketKey(String req) {
Pattern p = Pattern.compile("^(Sec-WebSocket-Key:).+",
Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
Matcher m = p.matcher(req);
if (m.find()) {
String foundstring = m.group();
return foundstring.split(":")[1].trim();
} else {
return null;
}
}
public static String base64Encode(byte[] input) {
return new String(org.apache.mina.util.Base64.encodeBase64(input));
}
// / <summary>
// /判断传入数据是否存在掩码
// / 传入数据:hi
// / socket接收到的二进制数据:
// / 1000000110000010 1101011011101001
// / 111110 111000 10111110 10000000
// / 掩码异或的操作:
// / 111110 111000 10111110 10000000
// / 进行异或^ 111110 111001 11010110 11101001
// / 结果: 1101000 1101001
// / 数据样例:
// / [0] 129 byte
// / [1] 130 byte
// / [2] 214 byte
// / [3] 233 byte
// / [4] 62 byte
// / [5] 56 byte
// / [6] 190 byte
// / [7] 128 byte
// / </summary>
// / <returns></returns>
public static String decode(byte[] receivedDataBuffer)
throws UnsupportedEncodingException {
String result = null;
// 计算非空位置
int lastStation = receivedDataBuffer.length - 1;
// 利用掩码对org-data进行异或
int frame_masking_key = 1;
for (int i = 6; i <= lastStation; i++) {
frame_masking_key = i % 4;
frame_masking_key = frame_masking_key == 0 ? 4 : frame_masking_key;
frame_masking_key = frame_masking_key == 1 ? 5 : frame_masking_key;
receivedDataBuffer[i] = (byte) (receivedDataBuffer[i] ^ receivedDataBuffer[frame_masking_key]);
}
result = new String(receivedDataBuffer, 6, lastStation - 5, "UTF-8");
return result;
}
// / 对传入数据进行无掩码转换
public static byte[] encode(String msg) throws UnsupportedEncodingException {
// 掩码开始位置
int masking_key_startIndex = 2;
byte[] msgByte = msg.getBytes("UTF-8");
// 计算掩码开始位置
if (msgByte.length <= 125) {
masking_key_startIndex = 2;
} else if (msgByte.length > 65536) {
masking_key_startIndex = 10;
} else if (msgByte.length > 125) {
masking_key_startIndex = 4;
}
// 创建返回数据
byte[] result = new byte[msgByte.length + masking_key_startIndex];
// 开始计算ws-frame
// frame-fin + frame-rsv1 + frame-rsv2 + frame-rsv3 + frame-opcode
result[0] = (byte) 0x81; // 129
// frame-masked+frame-payload-length
// 从第9个字节开始是 1111101=125,掩码是第3-第6个数据
// 从第9个字节开始是 1111110>=126,掩码是第5-第8个数据
if (msgByte.length <= 125) {
result[1] = (byte) (msgByte.length);
} else if (msgByte.length > 65536) {
result[1] = 0x7F; // 127
} else if (msgByte.length > 125) {
result[1] = 0x7E; // 126
result[2] = (byte) (msgByte.length >> 8);
result[3] = (byte) (msgByte.length % 256);
}
// 将数据编码放到最后
for (int i = 0; i < msgByte.length; i++) {
result[i + masking_key_startIndex] = msgByte[i];
}
return result;
}
}
分享到:
相关推荐
WebSocket使得数据交换更加高效,特别适用于需要低延迟、高频率交互的应用,比如在线游戏、股票交易、实时聊天等场景。 Mina(Java Multithreaded Network Application Framework)是一个用Java编写的网络应用框架...
WebSocket是HTML5中引入的一种新的通信协议,它允许在客户端和服务器之间建立持久的全双工连接,从而实现双向通信。相较于传统的HTTP协议,WebSocket在实时性和效率上有显著优势,特别适合于需要实时数据交互的应用...
【基于HTML5的JavaWeb聊天室】是一种使用HTML5、Java和相关技术构建的实时通信应用,它允许用户通过Web浏览器进行在线对话。这个Java聊天室的Demo是为初学者设计的,旨在帮助他们理解如何将这些技术整合到实际项目中...
在"Html5 Websocket聊天"项目中,服务端采用了基于Java的MINA通信框架。MINA(Multi-purpose Infrastructure for Network Applications)是一个高性能、异步事件驱动的网络应用框架,常用于构建高性能的TCP和UDP...
基于Java的米娜框架,报告对使用基于Java、websocket协议的网页聊天室的过程和技术做了详细的叙述首先,对现有网页进行了分析与评价。首先, 启动后台服务器,然后连接站点,客户端在pc端输入网站或者在手机端扫...
在本篇博文中,我们将深入探讨如何利用...通过以上步骤,你可以构建一个安全的、基于TLS/SSL的Java NIO服务器,确保数据在客户端和服务器之间的安全传输。MINA的灵活性和高性能特性使其成为实现此类应用的理想选择。
4. **SmartFoxServer 是专门为Adobe Flash设计的跨平台socket服务器**:SmartFoxServer是一款流行的实时多人在线游戏服务器,它也基于Java和非阻塞I/O,与MINA类似。这个信息可能是为了对比或展示MINA如何被用于类似...
Mina框架和Spring框架的结合,为开发者提供了一种高效、灵活的方式来实现这样的系统,特别是多人聊天室程序。下面我们将详细探讨如何利用这两个强大的工具来构建一个稳定且功能丰富的聊天室应用。 Mina框架,全称...
【Mina聊天室】是一个基于Apache Mina框架构建的简易聊天应用。Apache Mina是一个高度可扩展的网络通信框架,它简化了开发高性能且高可用性的网络应用,如TCP/IP和UDP服务。在这个项目中,Mina被用作底层通信引擎,...
Java Mina是一个高性能、异步事件驱动的网络应用程序框架,主要用于简化开发服务器端和客户端的网络应用。这个“java mina组合包”看起来包含了Mina库的所有必要组件和可能的扩展,为开发者提供了完整的开发环境。 ...
基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发源码-mina高性能Java网络框架.zip 基于java的开发...
标题中的“服务端基于MINA2的UDP双向通信Demo演示(Java客户端)”是指使用Apache MINA框架在Java中实现的UDP(用户数据报协议)的双向通信示例。MINA是一个高性能、异步的网络应用程序框架,常用于构建网络服务,如...
Mina 网络应用程序框架是基于 Java NIO 技术的异步 I/O 和事件驱动机制,提供了一个高效的网络应用程序开发框架。该框架使用事件驱动机制,能够帮助用户开发出高效的高可靠性的网络应用程序。 有限状态机是一种数学...
WebSocket是一种在浏览器和服务器之间建立持久性连接的协议,允许实时、双向数据传输,非常适合实时应用,如聊天室、股票交易系统或者在线游戏。 1. **Vue.js 部分**: Vue.js 的部分主要涉及以下组件和方法: - ...
在本项目中,它被用来实现一个多人聊天室,使得多个用户可以同时在线交流。Mina提供了一个高效的I/O处理模型,允许开发者以事件驱动和异步的方式编写网络应用,这在处理大量并发连接时尤其有用。 Mina的核心概念...
在本示例中,我们将深入探讨一个基于Mina实现的客户端-服务器简易Demo,这将帮助我们快速理解Mina的核心概念和用法。 首先,让我们来看看“minaServer”部分。Mina服务器端主要负责监听网络连接、接收客户端请求并...
《基于Mina与Spring构建的聊天室程序详解》 在当今的互联网世界中,实时通信技术扮演着至关重要的角色,而Mina与Spring框架的结合则为开发高效、稳定的聊天室程序提供了强大的支持。本文将深入探讨如何利用Mina作为...
在本实例中,我们将探讨如何使用Apache Mina2构建一个简单的服务器和客户端。 首先,让我们了解一下Mina2的核心概念。Mina2基于Java NIO(Non-blocking I/O)库,提供了异步I/O操作,这意味着它不会因为等待数据而...
这个框架基于Java语言,适用于开发TCP、UDP等网络协议的应用,如HTTP服务器、FTP服务器、聊天服务器等。在本项目中,"MINA_Server_Test"是一个实现了MINA服务器端功能的可运行示例。 首先,我们来详细了解一下MINA...