最近学习使用Netty, 目的是写一个socke 服务器与客户端,实现服务器主动向客户端查询数据,并同步返回结果。
思路是采用LinkedBlockingDeque数据队列实现,服务器向客户端发送一个带ID的信息,以该ID创建数据队列,并take()等待数据结果。
客户端收到信息后处理并向服务器发送该ID数据, 服务器接受数据后,向该ID队列添加数据,take()到信息后 删除该数据队列。
take()方法会一直等待结果,加一个定时任务去模拟发生信息结束该队列,防止长时间的等待。
贴代码:
客户端ClientHandler
@Override
protected void messageReceived(ChannelHandlerContext channelHandlerContext, BaseMsg baseMsg) throws Exception {
//接收服务端发送来的信息
MsgType msgType = baseMsg.getType();
try {
switch (msgType){
case LOGIN:{
//向服务器发起登录
NettyClient.sendMsg(new LoginMsg("001"));
System.out.println("客户端 进行登录请求 ..");
}break;
case PING:{
//接受服务器Ping命令
System.out.println("来自服务器的心跳连接回应!..");
}break;
case QUERY:{
//客户端接收查询信息
QueryMsg queryMsg = (QueryMsg) baseMsg;
//模拟数据查询
JSONObject data = queryDatas(queryMsg);
queryMsg.setResultData(data);
//想服务器发生数据
NettyClient.sendMsg(queryMsg);
}break;
default:break;
}
} catch (Exception e) {
e.printStackTrace();
}
ReferenceCountUtil.release(msgType);
}
/**
* 模拟数据查询
* @param content
* @return
* @throws InterruptedException
*/
private JSONObject queryDatas(QueryMsg query) throws InterruptedException{
JSONObject datas = new JSONObject();
TimeUnit.SECONDS.sleep(1);//模拟数据查询等待。
switch (query.getQueryType()) {
case INFO:{
datas.put("Id", query.getEquId());
datas.put("Name", "查询数据1");
datas.put("Type", "A");
datas.put("time", "0000-00-00 00:00:00");
}break;
case LOG:{
datas.put("A", query.getEquId());
datas.put("B", 0);
datas.put("C", "0");
datas.put("D", false);
datas.put("E", "");
datas.put("F", "");
datas.put("G", 20);
}break;
default:
break;
}
return datas;
}
/