Spring Boot 실전 의 netty-socketio 구현 간단 한 채 팅 방(지정 한 사용자 에 게 메 시 지 를 전송)

16310 단어 springboot
인터넷 의 많은 예 들 이 단체 로 보 낸 것 이다.본 고 는 일대일 발송 을 실현 하고 지 정 된 클 라 이언 트 에 게 메 시 지 를 전송 한다.
1.본 고 는 netty-socketio 오픈 소스 라 이브 러 리 와 MySQL 을 사용 하기 때문에 먼저 pom.xml 에 해당 하 는 의존 라 이브 러 리 를 추가 합 니 다.

<dependency> 
    <groupId>com.corundumstudio.socketio</groupId> 
    <artifactId>netty-socketio</artifactId> 
    <version>1.7.11</version> 
</dependency> 
<dependency> 
    <groupId>org.springframework.boot</groupId> 
  <artifactId>spring-boot-starter-data-jpa</artifactId> 
</dependency> 
<dependency> 
  <groupId>mysql</groupId> 
  <artifactId>mysql-connector-java</artifactId> 
</dependency> 
2.application.properties 를 수정 하고 포트 와 호스트 데이터베이스 연결 등 관련 설정 을 추가 합 니 다.

wss.server.port=8081 
wss.server.host=localhost 
 
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/springlearn 
spring.datasource.username = root 
spring.datasource.password = root 
spring.datasource.driverClassName = com.mysql.jdbc.Driver 
 
# Specify the DBMS 
spring.jpa.database = MYSQL 
# Show or not log for each sql query 
spring.jpa.show-sql = true 
# Hibernate ddl auto (create, create-drop, update) 
spring.jpa.hibernate.ddl-auto = update 
# Naming strategy 
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy 
# stripped before adding them to the entity manager) 
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect 
3.응용 프로그램 파일 을 수정 하고 nettysocket 에 대한 설정 정 보 를 추가 합 니 다.

package com.xiaofangtech.sunt; 
 
import org.springframework.beans.factory.annotation.Value; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import org.springframework.context.annotation.Bean; 
 
import com.corundumstudio.socketio.AuthorizationListener; 
import com.corundumstudio.socketio.Configuration; 
import com.corundumstudio.socketio.HandshakeData; 
import com.corundumstudio.socketio.SocketIOServer; 
import com.corundumstudio.socketio.annotation.SpringAnnotationScanner; 
 
@SpringBootApplication 
public class NettySocketSpringApplication { 
 
  @Value("${wss.server.host}") 
  private String host; 
 
  @Value("${wss.server.port}") 
  private Integer port; 
   
  @Bean 
  public SocketIOServer socketIOServer()  
  { 
    Configuration config = new Configuration(); 
    config.setHostname(host); 
    config.setPort(port); 
     
    //             
    config.setAuthorizationListener(new AuthorizationListener() { 
      @Override 
      public boolean isAuthorized(HandshakeData data) { 
        //http://localhost:8081?username=test&password=test 
        //            connect,                ,         
//       String username = data.getSingleUrlParam("username"); 
//       String password = data.getSingleUrlParam("password"); 
        return true; 
      } 
    }); 
     
    final SocketIOServer server = new SocketIOServer(config); 
    return server; 
  } 
   
  @Bean 
  public SpringAnnotationScanner springAnnotationScanner(SocketIOServer socketServer) { 
    return new SpringAnnotationScanner(socketServer); 
  } 
   
  public static void main(String[] args) { 
    SpringApplication.run(NettySocketSpringApplication.class, args); 
  } 
} 
4.메시지 구조 류 MessageInfo.java 추가

package com.xiaofangtech.sunt.message; 
 
public class MessageInfo { 
  //    id 
  private String sourceClientId; 
  //     id 
  private String targetClientId; 
  //     
  private String msgType; 
  //     
  private String msgContent; 
   
  public String getSourceClientId() { 
    return sourceClientId; 
  } 
  public void setSourceClientId(String sourceClientId) { 
    this.sourceClientId = sourceClientId; 
  } 
  public String getTargetClientId() { 
    return targetClientId; 
  } 
  public void setTargetClientId(String targetClientId) { 
    this.targetClientId = targetClientId; 
  } 
  public String getMsgType() { 
    return msgType; 
  } 
  public void setMsgType(String msgType) { 
    this.msgType = msgType; 
  } 
  public String getMsgContent() { 
    return msgContent; 
  } 
  public void setMsgContent(String msgContent) { 
    this.msgContent = msgContent; 
  } 
} 
5.클 라 이언 트 정 보 를 추가 하여 클 라 이언 트 의 sessionid 를 저장 합 니 다.

package com.xiaofangtech.sunt.bean; 
 
import java.util.Date; 
 
import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 
import javax.validation.constraints.NotNull; 
 
@Entity 
@Table(name="t_clientinfo") 
public class ClientInfo { 
  @Id 
  @NotNull 
  private String clientid; 
  private Short connected; 
  private Long mostsignbits; 
  private Long leastsignbits; 
  private Date lastconnecteddate; 
  public String getClientid() { 
    return clientid; 
  } 
  public void setClientid(String clientid) { 
    this.clientid = clientid; 
  } 
  public Short getConnected() { 
    return connected; 
  } 
  public void setConnected(Short connected) { 
    this.connected = connected; 
  } 
  public Long getMostsignbits() { 
    return mostsignbits; 
  } 
  public void setMostsignbits(Long mostsignbits) { 
    this.mostsignbits = mostsignbits; 
  } 
  public Long getLeastsignbits() { 
    return leastsignbits; 
  } 
  public void setLeastsignbits(Long leastsignbits) { 
    this.leastsignbits = leastsignbits; 
  } 
  public Date getLastconnecteddate() { 
    return lastconnecteddate; 
  } 
  public void setLastconnecteddate(Date lastconnecteddate) { 
    this.lastconnecteddate = lastconnecteddate; 
  } 
   
} 
6.조회 데이터베이스 인터페이스 클 라 이언 트 InfoRepository.java 추가

package com.xiaofangtech.sunt.repository; 
 
import org.springframework.data.repository.CrudRepository; 
 
import com.xiaofangtech.sunt.bean.ClientInfo; 
 
public interface ClientInfoRepository extends CrudRepository<ClientInfo, String>{ 
  ClientInfo findClientByclientid(String clientId); 
} 
7.메시지 처리 클래스 MessageEventHandler.Java 추가

package com.xiaofangtech.sunt.message; 
 
import java.util.Date; 
import java.util.UUID; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
 
import com.corundumstudio.socketio.AckRequest; 
import com.corundumstudio.socketio.SocketIOClient; 
import com.corundumstudio.socketio.SocketIOServer; 
import com.corundumstudio.socketio.annotation.OnConnect; 
import com.corundumstudio.socketio.annotation.OnDisconnect; 
import com.corundumstudio.socketio.annotation.OnEvent; 
import com.xiaofangtech.sunt.bean.ClientInfo; 
import com.xiaofangtech.sunt.repository.ClientInfoRepository; 
 
@Component 
public class MessageEventHandler  
{ 
  private final SocketIOServer server; 
   
  @Autowired 
  private ClientInfoRepository clientInfoRepository; 
   
  @Autowired 
  public MessageEventHandler(SocketIOServer server)  
  { 
    this.server = server; 
  } 
  //  connect  ,           ,    clientid sessionid      
  //                 client, 
  @OnConnect 
  public void onConnect(SocketIOClient client) 
  { 
    String clientId = client.getHandshakeData().getSingleUrlParam("clientid"); 
    ClientInfo clientInfo = clientInfoRepository.findClientByclientid(clientId); 
    if (clientInfo != null) 
    { 
      Date nowTime = new Date(System.currentTimeMillis()); 
      clientInfo.setConnected((short)1); 
      clientInfo.setMostsignbits(client.getSessionId().getMostSignificantBits()); 
      clientInfo.setLeastsignbits(client.getSessionId().getLeastSignificantBits()); 
      clientInfo.setLastconnecteddate(nowTime); 
      clientInfoRepository.save(clientInfo); 
    } 
  } 
   
  //  @OnDisconnect  ,          ,        
  @OnDisconnect 
  public void onDisconnect(SocketIOClient client) 
  { 
    String clientId = client.getHandshakeData().getSingleUrlParam("clientid"); 
    ClientInfo clientInfo = clientInfoRepository.findClientByclientid(clientId); 
    if (clientInfo != null) 
    { 
      clientInfo.setConnected((short)0); 
      clientInfo.setMostsignbits(null); 
      clientInfo.setLeastsignbits(null); 
      clientInfoRepository.save(clientInfo); 
    } 
  } 
   
  //      ,       ,         ,           ,         
  @OnEvent(value = "messageevent") 
  public void onEvent(SocketIOClient client, AckRequest request, MessageInfo data)  
  { 
    String targetClientId = data.getTargetClientId(); 
    ClientInfo clientInfo = clientInfoRepository.findClientByclientid(targetClientId); 
    if (clientInfo != null && clientInfo.getConnected() != 0) 
    { 
      UUID uuid = new UUID(clientInfo.getMostsignbits(), clientInfo.getLeastsignbits()); 
      System.out.println(uuid.toString()); 
      MessageInfo sendData = new MessageInfo(); 
      sendData.setSourceClientId(data.getSourceClientId()); 
      sendData.setTargetClientId(data.getTargetClientId()); 
      sendData.setMsgType("chat"); 
      sendData.setMsgContent(data.getMsgContent()); 
      client.sendEvent("messageevent", sendData); 
      server.getClient(uuid).sendEvent("messageevent", sendData); 
    } 
     
  } 
} 
8.ServerRunner.java 추가

package com.xiaofangtech.sunt.message; 
 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.CommandLineRunner; 
import org.springframework.stereotype.Component; 
 
import com.corundumstudio.socketio.SocketIOServer; 
 
@Component 
public class ServerRunner implements CommandLineRunner { 
  private final SocketIOServer server; 
 
  @Autowired 
  public ServerRunner(SocketIOServer server) { 
    this.server = server; 
  } 
 
  @Override 
  public void run(String... args) throws Exception { 
    server.start(); 
  } 
} 
9.공사 구조

10.테스트 실행
1)기본 데 이 터 를 추가 하고 데이터베이스 에 3 개의 클 라 이언 트 testclient 1,testclient 2,testclient 3 를 미리 설정 합 니 다.

2)클 라 이언 트 파일 index.html,index2.html,index 3.html 를 만 드 는 것 은 각각 testclient 1 testclient 2 testclient 3 세 사용 자 를 대표 합 니 다.
본문 은 직접 수정 했다https://github.com/mrniko/netty-socketio-demo/tree/master/client index.html 파일
그 중에서 clientid 는 발송 자 id 이 고 targetclientid 는 목표 측 id 이 며 본 고 는 발송 자 와 수신 자 를 html 파일 에 간단하게 기록 합 니 다.
다음 코드 로 연결 하기

io.connect('http://localhost:8081?clientid='+clientid); 
index.html 파일 내용 은 다음 과 같 습 니 다.

<!DOCTYPE html> 
<html> 
<head> 
 
    <meta charset="utf-8" /> 
 
    <title>Demo Chat</title> 
 
    <link href="bootstrap.css" rel="external nofollow" rel="stylesheet"> 
 
  <style> 
    body { 
      padding:20px; 
    } 
    #console { 
      height: 400px; 
      overflow: auto; 
    } 
    .username-msg {color:orange;} 
    .connect-msg {color:green;} 
    .disconnect-msg {color:red;} 
    .send-msg {color:#888} 
  </style> 
 
 
  <script src="js/socket.io/socket.io.js"></script> 
    <script src="js/moment.min.js"></script> 
    <script src="http://code.jquery.com/jquery-1.10.1.min.js"></script> 
 
  <script> 
 
    var clientid = 'testclient1'; 
    var targetClientId= 'testclient2'; 
     
    var socket = io.connect('http://localhost:8081?clientid='+clientid); 
 
    socket.on('connect', function() { 
      output('<span class="connect-msg">Client has connected to the server!</span>'); 
    }); 
 
    socket.on('messageevent', function(data) { 
      output('<span class="username-msg">' + data.sourceClientId + ':</span> ' + data.msgContent); 
    }); 
 
    socket.on('disconnect', function() { 
      output('<span class="disconnect-msg">The client has disconnected!</span>'); 
    }); 
 
        function sendDisconnect() { 
            socket.disconnect(); 
        } 
 
    function sendMessage() { 
            var message = $('#msg').val(); 
            $('#msg').val(''); 
 
            var jsonObject = {sourceClientId: clientid, 
                     targetClientId: targetClientId, 
                     msgType: 'chat', 
                     msgContent: message}; 
            socket.emit('messageevent', jsonObject); 
    } 
 
    function output(message) { 
            var currentTime = "<span class='time'>" + moment().format('HH:mm:ss.SSS') + "</span>"; 
            var element = $("<div>" + currentTime + " " + message + "</div>"); 
      $('#console').prepend(element); 
    } 
 
    $(document).keydown(function(e){ 
      if(e.keyCode == 13) { 
        $('#send').click(); 
      } 
    }); 
  </script> 
</head> 
 
<body> 
 
  <h1>Netty-socketio Demo Chat</h1> 
 
  <br/> 
 
  <div id="console" class="well"> 
  </div> 
 
    <form class="well form-inline" onsubmit="return false;"> 
      <input id="msg" class="input-xlarge" type="text" placeholder="Type something..."/> 
      <button type="button" onClick="sendMessage()" class="btn" id="send">Send</button> 
      <button type="button" onClick="sendDisconnect()" class="btn">Disconnect</button> 
    </form>  
</body>  
</html> 

3.본 테스트 시
testclient 1 에서 testclient 2 에 메 시 지 를 보 냅 니 다.
testclient 2 에서 testclient 1 에 메 시 지 를 보 냅 니 다.
testclient 3 에서 testclient 1 에 메 시 지 를 보 냅 니 다.
실행 결 과 는 다음 과 같다.


이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기