본문 바로가기
레디스

레디스(Redis)를 활용한 네띠 채팅 프로그램 구축: 간단한 적용 방법과 실시간 메시지 저장

by 플라퉁 2023. 3. 5.
728x90
반응형

 

 

 

이번에는 네띠를 사용한 채팅 프로그램에 레디스를 적용해 보겠습니다.

 

다음 실습의 연장선입니다. https://rhgustmfrh.tistory.com/29

 

네띠를 이용한 간단한 통신프로그램 실습 (채팅)

이번에도 간단한 채팅 프로그램을 만들면서 네띠를 배워봅시다. 채팅이 가장 기본인듯 하네요... 1. 디팬던시를 추가해 줍시다. io.netty netty-all 4.1.66.Final 메이븐이나 그래들 둘중에 원하시는걸 사

rhgustmfrh.tistory.com

 

<dependency>
   <groupId>redis.clients</groupId>
   <artifactId>jedis</artifactId>
   <version>3.7.0</version>
</dependency>

 

의존성을 추가하겠습니다. jedis는 자바에서 레디스를 사용하기 위한 라이브러리입니다.

 

챗서버를 수정하겠습니다.

 

package com.netty.chat.testChat.chatServer;

import io.netty.bootstrap.ServerBootstrap;
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.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.ArrayList;
import java.util.List;

public class ChatServer {
    private final int port;
    private final List<Channel> channels = new ArrayList<>();
    private JedisPool jedisPool;

    public ChatServer(int port) {
        this.port = port;
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(128);
        config.setMaxIdle(64);
        config.setMinIdle(16);
        config.setTestOnBorrow(true);
        this.jedisPool = new JedisPool(config, "localhost");
    }

    public void run() throws Exception {
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();

        try {
            ServerBootstrap bootstrap = new ServerBootstrap()
                    .group(bossGroup, workerGroup)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        public void initChannel(SocketChannel ch) throws Exception {
                            ChannelPipeline pipeline = ch.pipeline();
                            pipeline.addLast(new StringDecoder());
                            pipeline.addLast(new StringEncoder());
                            pipeline.addLast(new ChatServerHandler(channels, jedisPool.getResource()));
                        }
                    });

            ChannelFuture future = bootstrap.bind(port).sync();
            System.out.println("Server started on port " + port);

            future.channel().closeFuture().sync();
        } finally {
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
            jedisPool.close();
        }
    }

    public static void main(String[] args) throws Exception {
        new ChatServer(8080).run();
    }
}

 

챗 서버 핸들러도 수정해 줍니다.

 

package com.netty.chat.testChat.chatServer;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.util.List;
import java.util.Set;

public class ChatServerHandler extends ChannelInboundHandlerAdapter {
    public ChatServerHandler(List<Channel> channels, Jedis resource) {
    }
    JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "localhost");


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        String message = (String) msg;
        System.out.println("Received message from client: " + message);

        // Broadcast the message to all connected clients except the sender
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            Set<String> channelKeys = jedis.keys("*");
            for (String channelKey : channelKeys) {
                jedis.publish(channelKey, "[" + ctx.channel().remoteAddress() + "]: " + message + "\n");
            }
        } finally {
            if (jedis != null) {
                jedis.close();
            }
        }

        // Save the message to Redis
        try {
            jedis = jedisPool.getResource();
            String key = "chat_history";
            String value = "[" + ctx.channel().remoteAddress() + "]: " + message + "\n";
            jedis.append(key, value);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // Broadcast the message to all connected clients except the sender
        ctx.channel().parent().writeAndFlush("[" + ctx.channel().remoteAddress() + "]: " + message + "\n");
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}

 

 

이제 테스트를 해보면

일단 채팅은 잘 나오고 있군요

 

이제 레디스에 기록이 되는지 확인해 봅시다.

 

터미널을 2개 열고 하나는 redis-server ,하나는 redis-cli를 입력해 줍시다.

 

일단 레디스 서버는 잘 켜졌네요.

 

 

그리고 cli 창에서 GET 명령어로 key , value값으로 된 데이터를 찾아봅니다.

 

저는 chat_history 라는 key값으로 저장 했네요

 

자 value 값이 나오긴 했는데 알아볼수가 없군요 

 

일단 나오긴 했으니..

 

아무래도 레디스에서 저장을 최소로 하기 위해 이렇게 된듯 합니다. 

 

좀더 공부해 봅시다...

 

감사합니다.

 

 

 

 

728x90
반응형

댓글