文章目录
1.搭建netty服务器
1.创建maven项目
2.引入依赖
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>4.1.25.Final</version>
</dependency>
3.创建netty的main方法
package com.cxl.websco;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
public class WSServer {
public static void main(String[] args) throws InterruptedException {
EventLoopGroup mainGroup = new NioEventLoopGroup();
EventLoopGroup subGroup = new NioEventLoopGroup();
try {
ServerBootstrap serverBootstrap = new ServerBootstrap();
serverBootstrap.group(mainGroup,subGroup)
.channel(NioServerSocketChannel.class)
.childHandler(new WSServerInitialzer());
ChannelFuture channelFuture = serverBootstrap.bind(8083).sync();
channelFuture.channel().closeFuture().sync();
} finally {
mainGroup.shutdownGracefully();
mainGroup.shutdownGracefully();
}
}
}
4.创建初始化容器
package com.cxl.websco;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import io.netty.handler.stream.ChunkedWriteHandler;
public class WSServerInitialzer extends ChannelInitializer<SocketChannel>{
@Override
protected void initChannel(SocketChannel channel) throws Exception {
ChannelPipeline pipeline = channel.pipeline();
//编解码器
pipeline.addLast(new HttpServerCodec());
//对大数据流处理
pipeline.addLast(new ChunkedWriteHandler());
// 对httpmessage进行聚合,聚合成fullhttprequest或fullhttpresponse
// 几乎在netty中的编程都会使用到此hanler
pipeline.addLast(new HttpObjectAggregator(1024*64));
//===================以上是用于支持http协议===================
//websocket服务器处理的协议,用于指定给客户端连接访问的路由
pipeline.addLast(
new WebSocketServerProtocolHandler("/ws"));
//自定义拦截器
pipeline.addLast(new ChatHandler());
}
}
5.创建自定义拦截器
package com.cxl.websco;
import java.time.LocalDateTime;
import io.netty.channel.Channel;
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.channel.local.LocalChannel;
import io.netty.handler.codec.http.HttpObject;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import io.netty.util.concurrent.GlobalEventExecutor;
/**
* 处理消息的handler
* @author mingliang
*TextWebSocketFrame websocket专门处理文本的对象 ,frame是载体
*/
public class ChatHandler extends SimpleChannelInboundHandler<TextWebSocketFrame>{
//管理所有客户端的channel
private static ChannelGroup clients = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
@Override
protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
String content = msg.text(); // 获取客户端传过来的消息内容
System.out.println("msg : "+content);
for (Channel channel : clients) {
channel.writeAndFlush(
new TextWebSocketFrame
("[服务器在:]"+LocalDateTime.now()+
",接收到消息为:"+content));
}
//以下写法和for循环一致
// clients.writeAndFlush(new TextWebSocketFrame
// ("[服务器在:]"+LocalDateTime.now()+
// ",接收到消息为:"+content));
}
//用户进入
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
clients.add(ctx.channel());
System.out.println("添加cid" + ctx.channel().id());clients.add(ctx.channel());
}
//用户离开
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
clients.remove(ctx.channel());
System.out.println("移除cid" + ctx.channel().id());
System.out.println("移除长id" + ctx.channel().id().asLongText());
System.out.println("移除短id" + ctx.channel().id().asShortText());
}
}
2.编写前端页面
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title></title>
</head>
<body>
<div>发送消息:</div>
<input type="text" id="msgContent" />
<input type="button" value="点我发送" onclick="CHAT.chat()" />
<div>接收消息:</div>
<div id="receiveMsg" style="background-color: gainsboro;"></div>
<script type="application/javascript">
window.CHAT={
socket:null,
init:function(){
if(window.WebSocket){
CHAT.socket = new WebSocket("ws://pf4g8f.natappfree.cc/ws");
CHAT.socket.onopen = function(){
console.log("连接建立成功")
},
CHAT.socket.onmessage = function(e){
console.log("接收到消息:"+e.data)
var msg = document.getElementById("receiveMsg")
var html = msg.innerHTML;
msg.innerHTML = html +"<br/>"+ e.data;
},
CHAT.socket.onclose = function(){
console.log("连接关闭")
},
CHAT.socket.onerror = function(){
console.log("发生错误")
}
}else{
alert("浏览器不支持WebSocket")
}
},
chat:function(){
var msg = document.getElementById("msgContent");
CHAT.socket.send(msg.value);
},
}
CHAT.init();
</script>
</body>
</html>
3.搭建natapp服务器
官方网站:https://natapp.cn/
注册账号-登录-这里需要两个域名!
一个是netty服务器的公网域名,一个是公网域名
这边我购买了一个VIP1的,一个月也就几块钱
1.搭建nginx
去官网下载个nginx-win版
修改conf文件
#user nobody;
worker_processes 1;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 7777;
server_name localhost;
root D:/HBuilderProjects/WebChat/;
location / {
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
修改地方为
启动nignx
启动即可,然后访问localhost:7777/你的网页.html即可
如果访问的是nginx 的欢迎页面,请参照以上图片仔细检查(需要删除某一行)
2.搭建natapp映射
下载客户端
进入更目录,cmd,执行命令
natapp -authtoken=你的token
token怎么看?
启动后,需要对页面中的ws请求路径改为你请求的公网路径
把公网地址发给别人加上ADDRESS/你的页面.html 发给就可以了。