package cn.com.mengdou.im;
import static io.netty.handler.codec.http.HttpHeaders.Names.ACCESS_CONTROL_ALLOW_ORIGIN;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpHeaders.Names.HOST;
import static io.netty.handler.codec.http.HttpMethod.GET;
import static io.netty.handler.codec.http.HttpMethod.POST;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.handler.codec.http.multipart.Attribute;
import io.netty.handler.codec.http.multipart.DefaultHttpDataFactory;
import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http.multipart.InterfaceHttpData.HttpDataType;
import io.netty.handler.codec.http.websocketx.CloseWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PingWebSocketFrame;
import io.netty.handler.codec.http.websocketx.PongWebSocketFrame;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshaker;
import io.netty.handler.codec.http.websocketx.WebSocketServerHandshakerFactory;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @description:消息业务处理类
* @fileName:IMServerHandler.java
* @createTime:2015年7月23日 下午7:38:22
* @author:肖震
* @version 1.0.0
*
*/
public class IMServerHandler extends SimpleChannelInboundHandler<Object>
{ // (1)
public static ChannelGroup channels = new DefaultChannelGroup(
GlobalEventExecutor.INSTANCE);
private static final String WEBSOCKET_PATH = "/websocket";
// 在线用户状态map,由ip:在线状态组成
private static final Map<String, String> onlineMap = new HashMap<String, String>();
// 在线用户channel map,由ip:channel组成
private static final Map<String, Channel> onlineUserChannelMap = new HashMap<String, Channel>();
private WebSocketServerHandshaker handshaker;
@Override
public void handlerAdded(ChannelHandlerContext ctx)
throws Exception
{ // (2)
Channel incoming = ctx.channel();
for (Channel channel : channels)
{
channel.writeAndFlush("[SERVER] - " + incoming.remoteAddress()
+ " 加入\n");
}
channels.add(ctx.channel());
}
@Override
public void channelReadComplete(ChannelHandlerContext ctx)
{
ctx.flush();
}
@Override
public void handlerRemoved(ChannelHandlerContext ctx)
throws Exception
{
Channel incoming = ctx.channel();
for (Channel channel : channels)
{
channel.writeAndFlush("[SERVER] - " + incoming.remoteAddress()
+ " 离开\n");
}
channels.remove(ctx.channel());
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg)
throws Exception
{
// http请求
if (msg instanceof FullHttpRequest)
{
handleHttpRequest(ctx, (FullHttpRequest) msg);
}
else if (msg instanceof WebSocketFrame)// websocket请求
{
handleWebSocketFrame(ctx, (WebSocketFrame) msg);
}
}
/**
*
* @function: 获得本地webscoket地址
* @param req:http请求对象
* @return String :返回地址字符串
* @exception
* @author:肖震
* @since 1.0.0
*/
private static String getWebSocketLocation(FullHttpRequest req)
{
String location = req.headers().get(HOST) + WEBSOCKET_PATH;
return "ws://" + location;
}
/**
*
* @function: 处理websocket请求业务
* @param ctx
* @param frame
* @exception
* @author:肖震
* @since 1.0.0
*/
private void handleWebSocketFrame(ChannelHandlerContext ctx,
WebSocketFrame frame)
{
// 是否关闭
if (frame instanceof CloseWebSocketFrame)
{
handshaker.close(ctx.channel(),
(CloseWebSocketFrame) frame.retain());
return;
}
// 是否ping
if (frame instanceof PingWebSocketFrame)
{
ctx.channel().write(
new PongWebSocketFrame(frame.content().retain()));
return;
}
// 非文本
if (!(frame instanceof TextWebSocketFrame))
{
throw new UnsupportedOperationException(String.format(
"%s frame types not supported", frame.getClass().getName()));
}
// 接收到的消息
String s = ((TextWebSocketFrame) frame).text();
// 发送者的通道
Channel incoming = ctx.channel();
System.out.println("收到客户[" + incoming.remoteAddress() + "]消息:" + s);
// 从发送消息解析出接收人的用户id
String acceptUserId = null;
// 解析出接收者的用户id
if (s != null && s.contains("||-||"))
{
acceptUserId = s.split("||-||")[1];
}
// 点对点发送消息
if (acceptUserId != null)
{
Channel channel = onlineUserChannelMap.get(acceptUserId);
if (channel != null)
{
channel.writeAndFlush(new TextWebSocketFrame("["
+ channel.remoteAddress() + "]:" + s + "\n"));
}
}
else
// 群发消息
{
for (Channel channel : channels)
{
if (channel != incoming)
{
channel.writeAndFlush(new TextWebSocketFrame("["
+ channel.remoteAddress() + "]:" + s + "\n"));
}
else
{
channel.writeAndFlush(new TextWebSocketFrame("["
+ incoming.remoteAddress() + "]:" + s + "\n"));
}
}
}
}
/**
*
* @function: http请求处理
* @param ctx
* @param req
* @throws Exception
* @exception
* @author:肖震
* @since 1.0.0
*/
private void handleHttpRequest(ChannelHandlerContext ctx,
FullHttpRequest req)
throws Exception
{
System.out.println("handleHttpRequest method=========="
+ req.getMethod());
System.out.println("handleHttpRequest uri==========" + req.getUri());
// http get请求
if (req.getMethod() == GET)
{
httpGetDeal(ctx, req);
}
if (req.getMethod() == POST)
{
httpPostDeal(ctx, req);
return;
}
}
/**
* @function: http post方式处理
* @param ctx
* @param req
* @throws IOException
* @exception
* @author:肖震
* @since 1.0.0
*/
private void httpPostDeal(ChannelHandlerContext ctx, FullHttpRequest req)
throws IOException
{
// 处理POST请求
HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(
new DefaultHttpDataFactory(false), req);
InterfaceHttpData postData = decoder.getBodyHttpData("q"); // //
// 读取从客户端传过来的参数
String question = "";
if (postData.getHttpDataType() == HttpDataType.Attribute)
{
Attribute attribute = (Attribute) postData;
question = attribute.getValue();
System.out.println("q:" + question);
}
if (question != null && !question.equals(""))
{
String data = question;
FullHttpResponse res = new DefaultFullHttpResponse(HTTP_1_1, OK,
Unpooled.wrappedBuffer(data.getBytes(CharsetUtil.UTF_8)));
res.headers().set(CONTENT_TYPE, "text/html; charset=UTF-8");
res.headers().set(ACCESS_CONTROL_ALLOW_ORIGIN, "*");
res.headers().set(CONTENT_LENGTH, res.content().readableBytes());
sendHttpResponse(ctx, req, res);
}
return;
}
/**
* @function: http get�
没有合适的资源?快使用搜索试试~ 我知道了~
Spring3Websocket
共41个文件
xml:12个
class:6个
java:6个
2星 需积分: 21 71 下载量 52 浏览量
2017-10-26
15:38:32
上传
评论
收藏 37KB RAR 举报
温馨提示
Spring3Websocket,好难找的资源, Spring3Websocket做此备份
资源推荐
资源详情
资源评论
收起资源包目录
Spring3Websocket.rar (41个子文件)
Spring3Websocket
.project 1KB
pom.xml 5KB
target
test-classes
m2e-wtp
web-resources
META-INF
maven
cn.com
Spring3Websocket
pom.xml 5KB
pom.properties 248B
MANIFEST.MF 105B
classes
spring-mybatis.xml 4KB
cn
com
mengdou
im
IMServerInitializer.class 2KB
IMServerHandler.class 14KB
IMServer.class 2KB
dao
TestDao.class 284B
TestDao.xml 210B
websocket
WebSocket.class 3KB
controller
TestController.class 1KB
spring-mvc.xml 3KB
jdbc.properties 407B
logback.xml 2KB
.settings
.jsdtscope 575B
org.eclipse.wst.common.component 689B
org.eclipse.wst.validation.prefs 50B
org.eclipse.jdt.core.prefs 430B
org.eclipse.wst.common.project.facet.core.xml 252B
org.eclipse.wst.jsdt.ui.superType.container 49B
org.eclipse.m2e.core.prefs 90B
org.eclipse.wst.jsdt.ui.superType.name 6B
src
main
resources
spring-mybatis.xml 4KB
spring-mvc.xml 3KB
jdbc.properties 407B
logback.xml 2KB
java
cn
com
mengdou
im
IMServerHandler.java 13KB
IMServer.java 1KB
IMServerInitializer.java 922B
dao
TestDao.java 191B
TestDao.xml 210B
websocket
WebSocket.java 3KB
controller
TestController.java 981B
webapp
WEB-INF
web.xml 2KB
jsp
siri.jsp 2KB
chat.jsp 4KB
showUser.jsp 269B
index.jsp 52B
.classpath 1KB
共 41 条
- 1
资源评论
- helloxiaoyun2018-03-21正在使用,结果稍后追评
- mengxiang4162018-07-14非常好,学习到了,感谢分享
- fbbzl2017-12-18正在使用,结果稍后追评
- caoco2018-06-10本以为是spring 提供的websocket,其实是自己写的一个小服务器,不是想用的,请下面的评论写真实点,不要害后来人。
飞扬紫云
- 粉丝: 10
- 资源: 147
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功