web

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>聊天室</title>
</head>
<body>
<script type="text/javascript">var socket;var uid;if (window.WebSocket){console.log("ok")} else {alert("浏览器不支持")}function bindSocket(){socket = new WebSocket("ws://127.0.0.1:8080/ws")socket.onmessage = function (ev) {var ta = document.getElementById("resultText")var d = JSON.parse(ev.data)if(d.type == 2){ta.value = ta.value + "\n" + d.content} else {ta.value = ta.value + "\n" + ev.data}}socket.onopen = function (ev) {document.getElementById('msgText').style.display = 'inline'document.getElementById('bind').style.display = 'none'var ta = document.getElementById("resultText")ta.value = "连接成功"if(uid != null){document.getElementById('uid').innerHTML = uidsocket.send(JSON.stringify({"type":1, "content":uid}))}}socket.onclose = function (ev) {var ta = document.getElementById("resultText")ta.value = ta.value + "\n" + "连接关闭"}}function send(type, message) {if (!window.WebSocket) {return} else {if(socket == null){bindSocket()uid = message}}console.log(socket.readyState)if (socket.readyState == WebSocket.OPEN && type == 2){console.log(type, message)socket.send(JSON.stringify({"type":type, "content":message}))}}</script><form onsubmit="return false;"><div id="bind"><input type="text" name="uid"></input><input type="button" value="绑定" onclick="send(1,this.form.uid.value);"><br/></div><div id="msgText" style="display: none;"><h3 id="uid"></h3><textarea name="message" style="width: 400px;height: 30px"></textarea><input type="button" value="发送消息" onclick="send(2, this.form.message.value);"><h3>聊天框</h3><textarea id="resultText" style="width: 400px;height: 100px"></textarea><input type="button" onclick="javascript:document.getElementById('resultText').value=''" value="清空内容"></div></form>
</body>
</html>

后端

server

import java.util.List;
import java.util.Map;import com.google.common.collect.Lists;
import com.google.common.collect.Maps;import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.util.concurrent.GlobalEventExecutor;
import lombok.Data;public class WSWebNettyServer {public static final int port = 8080;public static void main(String[] args) throws Exception {new WSWebNettyServer().start();}public void start() throws Exception {ConsoleUtil.println("start");EventLoopGroup pGroup = new NioEventLoopGroup();EventLoopGroup cGroup = new NioEventLoopGroup();try {ServerBootstrap bootstrap = new ServerBootstrap();WSConsoleServerHandler handler = new WSConsoleServerHandler();bootstrap.option(ChannelOption.SO_BACKLOG, 1024).group(pGroup, cGroup).channel(NioServerSocketChannel.class).childOption(ChannelOption.SO_KEEPALIVE, true).childHandler(new ChannelInitializer<SocketChannel>() {@Overrideprotected void initChannel(SocketChannel ch) throws Exception {ch.pipeline().addLast(new HttpServerCodec()).addLast(new ChunkedWriteHandler()).addLast(new HttpObjectAggregator(8192)).addLast(handler).addLast(new WebSocketServerProtocolHandler("/ws", null, true, 65536 * 10));}});ChannelFuture f = bootstrap.bind(port).sync();f.channel().closeFuture().sync();} catch (Exception e) {e.printStackTrace();} finally {pGroup.shutdownGracefully();cGroup.shutdownGracefully();}ConsoleUtil.println("end");}}@Sharable
class WSConsoleServerHandler extends ChannelInboundHandlerAdapter {private static Map<String, ChannelId> channelMap = Maps.newHashMap();private static Map<String, String> keyMap = Maps.newHashMap();private static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);@Overridepublic void channelActive(ChannelHandlerContext ctx) throws Exception {channelGroup.add(ctx.channel());ConsoleUtil.println("up " + ctx.channel().remoteAddress());super.channelActive(ctx);}@Overridepublic void channelInactive(ChannelHandlerContext ctx) throws Exception {channelGroup.remove(ctx.channel());ConsoleUtil.println("down " + ctx.channel().remoteAddress());super.channelInactive(ctx);}@Overridepublic void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {cause.printStackTrace();ctx.close();ConsoleUtil.println("error " + ctx.channel().remoteAddress());super.exceptionCaught(ctx, cause);}@Overridepublic void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {if (null != msg && msg instanceof FullHttpRequest) {ConsoleUtil.println("receive request : " + msg.getClass());} else if (null != msg && msg instanceof TextWebSocketFrame) {TextWebSocketFrame frame = (TextWebSocketFrame) msg;ConsoleUtil.println("receive web : " + frame.text());WsWebJsonData data = JsonUtil.decode(frame.text(), WsWebJsonData.class);if(WsWebJsonData.USERID_TYPE.equals(data.getType())){channelMap.put(data.getContent().toString(), ctx.channel().id());keyMap.put(ctx.channel().id().asLongText(), data.getContent().toString());} else if(WsWebJsonData.MESSAGE_TYPE.equals(data.getType())) {data.setContent(keyMap.get(ctx.channel().id().asLongText()) + ": " + data.getContent());pushMessage(ctx, data);}} else {ConsoleUtil.println("receive : " + msg.getClass());}super.channelRead(ctx, msg);}public Channel getChannel(String channelKey) {if(channelMap.get(channelKey) != null) {return channelGroup.find(channelMap.get(channelKey));}return null;}public void pushMessage(ChannelHandlerContext ctx, Object message) {List<String> rmKeys = Lists.newArrayList();for(String key : channelMap.keySet()) {Channel channel = getChannel(key);if(channel != null && channel.isActive()) {channel.writeAndFlush(new TextWebSocketFrame(JsonUtil.encode(message)));} else {rmKeys.add(key);}}for(String key : rmKeys) {channelMap.remove(key);}}}@Data
class WsWebJsonData {public static final Integer USERID_TYPE = 1;public static final Integer MESSAGE_TYPE = 2;private Integer type;private Object content;public WsWebJsonData(Integer type, Object content) {super();this.type = type;this.content = content;}public WsWebJsonData(){}}

工具类

import java.text.SimpleDateFormat;
import java.util.Date;public class ConsoleUtil {private static String format = "yyyy-MM-dd HH:mm:ss.SSS";public static void println(Object obj) {System.out.println(convertToString(System.currentTimeMillis()) + " : " + obj);}private static String convertToString(Long date) {SimpleDateFormat formater = new SimpleDateFormat(format);try {return formater.format(new Date(date));} catch (Exception e) {return null;}}public static void println(String format, Object ... objs) {System.out.println(convertToString(System.currentTimeMillis()) + " : " + String.format(format, objs));}
}import com.alibaba.fastjson.JSON;public class JsonUtil {public static <T> T decode(String json, Class<T> clazz){return JSON.parseObject(json, clazz);}public static String encode(Object obj) {String json = JSON.toJSONString(obj);return json;}}

效果

Netty + Web聊天室相关推荐

  1. 御神楽的学习记录之Springboot+netty实现Web聊天室

    文章目录 前言 一.Netty简介 1.介绍 二.Web聊天室实现 1.Idea项目创建 2.java类编写 3.html测试 总结 参考 前言 WebSocket是一种在单个TCP连接上进行全双工通 ...

  2. 利用html 5 websocket做个山寨版web聊天室(手写C#服务器)

    在之前的博客中提到过看到html5 的websocket后很感兴趣,终于可以摆脱长轮询(websocket之前的实现方式可以看看Developer Works上的一篇文章,有简单提到,同时也说了web ...

  3. Netty实现聊天室

    文章目录 注:更多netty相关文章请访问博主专栏: netty专栏 本文内容基于上一篇博客 netty实现WebSocket协议,一些基本使用请参考该博客. 本例实现的功能: 有新成员加入时,群广播 ...

  4. Springboot实现Web聊天室

    Springboot实现Web聊天室 一.项目创建 二.代码编写 三.测试 四.参考 一.项目创建 新建Spring项目,选择JDK版本: 选择Spring Web: 二.代码编写 导入.jar包: ...

  5. 基于阿里云用C/C++做了一个http协议与TCP协议的web聊天室的服务器——《干饭聊天室》

    基于阿里云用C/C++做了一个http协议与TCP协议的web聊天室的服务器--<干饭聊天室> 在这里首先感谢前端小伙伴飞鸟 前端技术请看一款基于React.C++,使用TCP/HTTP协 ...

  6. netty加载html文件的原理,Netty+html聊天室入门

    1)服务端 ChatServer.java package chat; import chat.handler.WSServerInitializer; import io.netty.bootstr ...

  7. Django项目--web聊天室

    需求 做一个web聊天室,主要练习前端ajax与后台的交互: 一对一聊天和群组聊天 添加用户为好友 搜索并添加群组 管理员可以审批用户加群请求,群管理员可以有多个,群管理员可以删除,添加禁言群友 与聊 ...

  8. 使用FastHttpApi构建多人Web聊天室

    为什么80%的码农都做不了架构师?>>>    一般在dotnet core下构建使用web服务应用都使用asp.net core,但通过FastHttpApi组建也可以方便地构建w ...

  9. 基于.NET SingalR,LayIM2.0实现的web聊天室

    LayIM官网 http://www.layui.com/doc/layim.html 博客教程:http://www.cnblogs.com/panzi/p/5767095.html 项目说明:基于 ...

最新文章

  1. 还在为投文章发愁吗,也许你更适合审别人的文章——JGG期刊专职编辑招聘(IF4)...
  2. 【Flutter】Future 异步编程 ( 简介 | then 方法 | 异常捕获 | async、await 关键字 | whenComplete 方法 | timeout 方法 )
  3. TalkingData:用好大数据,为企业转型赋能
  4. C# 去重处理字符大小写
  5. IntelliJ IDEA创建web项目及异常问题解决
  6. 反射机制2,Class类的使用
  7. vue2 watch引用类型 失败原因
  8. 一个简单的VC++案例:显示年月日
  9. java byte[]如何移动位置_《北京尚学堂学习》——java基础
  10. php 京东 联盟 链接,完整的京东联盟自定义推广链接生产程序
  11. Packet Tracer 思科模拟器入门教程 之十一 路由器静态路由配置
  12. 基于几何图形搭建障碍物地图的方法(MATLAB)
  13. Nginx 上传图片500错误
  14. 平行四边形 java_Java编写三角形和平行四边形
  15. linux使用入门debian,Debian 7.7入门安装与配置
  16. 80后最牛的辞职信+出师表
  17. P2973 [USACO10HOL]赶小猪
  18. 三星s4流量显示无服务器,揭开隐藏功能的面纱 GALAXY S4使用指南
  19. 终焉誓约怎么用电脑玩 终焉誓约模拟器玩法教程
  20. JAVA Base64加密解密

热门文章

  1. 转载:farey(法莱)数列
  2. HTML 绘制曲线图
  3. 日月光华深度学习(四)-计算机视觉-卷积神经网络
  4. linux分区出现hfs,在Arch Linux上挂载HFS +分区
  5. 零基础学Java语言---编程题
  6. github在线修改文章
  7. 听课记录(09/22)
  8. 服务器中所有文件夹变只读,我的电脑里全部文件夹属性都变成只读了改也改不过来...
  9. Socks5代理和IP代理
  10. Go context.Context的学习