JAVA Netty 채 팅 방+채 팅 기능 구현 예시 코드
Netty 프레임 워 크 를 사용 하여 채 팅 방 기능 을 실현 하고 서버 는 클 라 이언 트 의 상하 한 상 태 를 감시 하고 메 시 지 를 전달 할 수 있 습 니 다.점 대 점 잡담 기능 도 동시에 실현 했다.기술 점 에서 나 는 모두 코드 에 비 고 를 했 는데,여 기 는 더 이상 반복 해서 쓰 지 않 는 다.netty 를 배우 고 싶 은 학생 들 에 게 참고 가 되 었 으 면 좋 겠 습 니 다.
서버 코드
서버 입구 코드
package nio.test.netty.groupChat;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
/**
* netty
* @author zhang
*
*/
public class NettyChatServer {
private int port;
public NettyChatServer(int port){
this.port = port;
}
// netty
private void init() throws Exception{
EventLoopGroup boss = new NioEventLoopGroup(1);
EventLoopGroup work = new NioEventLoopGroup(16);
try {
ServerBootstrap boot = new ServerBootstrap();
boot.group(boss,work);
boot.channel(NioServerSocketChannel.class);// boss selector channel
boot.option(ChannelOption.SO_BACKLOG, 128);//boss
boot.childOption(ChannelOption.SO_KEEPALIVE, true); //
boot.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
// channel pipeline Handler
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("encoder",new StringEncoder());
pipeline.addLast("decoder",new StringDecoder());
pipeline.addLast(new ServerMessageHandler());// Handler
}
});
System.out.println(" ...");
//
ChannelFuture channelFuture = boot.bind(port).sync();
channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future)
throws Exception {
if(future.isSuccess()){
System.out.println(" ...");
}
if(future.isDone()){
System.out.println(" ...OK");
}
}
});
// channel
channelFuture.channel().closeFuture().sync();
channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future)
throws Exception {
if(future.isCancelled()){
System.out.println(" ..");
}
if(future.isCancellable()){
System.out.println(" ..OK");
}
}
});
}finally{
boss.shutdownGracefully();
work.shutdownGracefully();
}
}
/**
* main
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
new NettyChatServer(9090).init();
}
}
서버 쪽 메시지 처리 Handler
package nio.test.netty.groupChat;
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.util.concurrent.GlobalEventExecutor;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* Handler
* @author zhang
*
*/
public class ServerMessageHandler extends SimpleChannelInboundHandler<String>{
/**
* channel
* GlobalEventExecutor.INSTANCE
* channel ChannelGroup
* channel ,
*/
private static ChannelGroup channels = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
/**
* , key ,
*
* ChannelGroup
*/
private static Map<String,Channel> all = new HashMap<String,Channel>();
private SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
/**
*
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg)
throws Exception {
Channel channel = ctx.channel();
/**
* #
*/
if(msg.contains("#")){
String id = msg.split("#")[0];
String body = msg.split("#")[1];
Channel userChannel = all.get(id);
String key = channel.remoteAddress().toString().split(":")[1];
userChannel.writeAndFlush(sf.format(new Date())+"
【 】 "+key+" : "+body);
return;
}
//
for(Channel c : channels){
String addr = c.remoteAddress().toString();
if(channel !=c){
c.writeAndFlush(sf.format(new Date())+"
【 】 "+addr+" : "+msg);
}else{
c.writeAndFlush(sf.format(new Date())+"
【 】 "+addr+" : "+msg);
}
}
}
/**
*
*/
@Override
public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
String addr = channel.remoteAddress().toString();
/**
* ChannelGroup channel
*
*/
channels.writeAndFlush(sf.format(new Date())+"
【 】 "+addr+" ");
channels.add(channel);
String key = channel.remoteAddress().toString().split(":")[1];
all.put(key, channel);
}
/**
* channel
*/
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
String addr = ctx.channel().remoteAddress().toString();
System.out.println(sf.format(new Date())+"
【 】 "+addr+" ");
}
/**
* channel
*/
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
String addr = ctx.channel().remoteAddress().toString();
System.out.println(sf.format(new Date())+"
【 】 "+addr+" ");
//
String key = ctx.channel().remoteAddress().toString().split(":")[1];
all.remove(key);
}
/**
*
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
//System.out.println(" !");
ctx.close();
}
/**
*
* channel ChannelGroup
*/
@Override
public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
Channel channel = ctx.channel();
String addr = channel.remoteAddress().toString();
/**
* ChannelGroup channel
*
*/
channels.writeAndFlush(sf.format(new Date())+"
【 】 "+addr+" ");
// ChannelGroup
System.out.println(" :"+channels.size());
System.out.println("all:"+all.size());
}
}
클 라 이언 트 메 인 방법 코드
package nio.test.netty.groupChat;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import java.util.Scanner;
public class NettyChatClient {
private String ip;
private int port;
public NettyChatClient(String ip,int port){
this.ip = ip;
this.port = port;
}
/**
*
*/
private void init() throws Exception{
//
EventLoopGroup work = new NioEventLoopGroup();
try {
Bootstrap boot = new Bootstrap();
boot.group(work);
boot.channel(NioSocketChannel.class);
boot.handler(new ChannelInitializer<NioSocketChannel>() {
@Override
protected void initChannel(NioSocketChannel ch)
throws Exception {
ChannelPipeline pipeline = ch.pipeline();
pipeline.addLast("encoder",new StringEncoder());
pipeline.addLast("decoder",new StringDecoder());
pipeline.addLast(new ClientMessageHandler());
}
});
ChannelFuture channelFuture = boot.connect(ip, port).sync();
channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future)
throws Exception {
if(future.isSuccess()){
System.out.println(" ...");
}
if(future.isDone()){
System.out.println(" ...OK!");
}
}
});
System.out.println(channelFuture.channel().localAddress().toString());
System.out.println("#################################################");
System.out.println("~~~~~~~~~~~~~~ # ~~ ~~~~~~~~~~~~~~~~~~");
System.out.println("#################################################");
/**
*
*/
Channel channel = channelFuture.channel();
// channel
Scanner scanner = new Scanner(System.in);
while(scanner.hasNextLine()){
String str = scanner.nextLine();
channel.writeAndFlush(str+"
");
}
channelFuture.channel().closeFuture().sync();
scanner.close();
} finally {
work.shutdownGracefully();
}
}
/**
*
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception{
new NettyChatClient("127.0.0.1",9090).init();
}
}
클 라 이언 트 메시지 처리 핸들 러
package nio.test.netty.groupChat;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
/**
* Handler
* @author zhang
*
*/
public class ClientMessageHandler extends SimpleChannelInboundHandler<String> {
/**
*
*/
@Override
protected void channelRead0(ChannelHandlerContext ctx, String msg)
throws Exception {
System.out.println(msg);
}
/**
*
*/
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
throws Exception {
ctx.close();
}
}
테스트 결과네 개의 클 라 이언 트 서버 엔 드 로 그 를 시작 하 였 습 니 다.효 과 는 다음 과 같 습 니 다.
클 라 이언 트 로그:
클 라 이언 트 2 로그:
클 라 이언 트 3 로그:
클 라 이언 트 4 로그:
현재 클 라 이언 트 4 에서 메 시 지 를 보 냅 니 다:
모든 클 라 이언 트 가 메 시 지 를 받 을 수 있 습 니 다:
연화 클 라 이언 트 클 라 이언 트 닫 기 3:
서버 로그:
다른 클 라 이언 트 로그:
비공개 메시지 발송:
이 클 라 이언 트 는 메 시 지 를 받 을 수 없습니다.
JAVA Netty 가 채 팅 방+개인 채 팅 기능 을 실현 하 는 예시 코드 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 JAVA Netty 채 팅 방 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 읽 어 주시 기 바 랍 니 다.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
JAVA 객체 작성 및 제거 방법정적 공장 방법 정적 공장 방법의 장점 를 반환할 수 있습니다. 정적 공장 방법의 단점 류 공유되거나 보호된 구조기를 포함하지 않으면 이불류화할 수 없음 여러 개의 구조기 파라미터를 만났을 때 구축기를 고려해야 한다...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.