Spring Websocket + STOMP + Unity C# + WebSocketSharp 한글 처리 문제.

2020. 7. 31. 18:21프로그래밍/Unity3D

728x90
반응형

문제 : Unity엔진으로 게임을 개발 중에 한글 문제가 발생되었습니다.

Client에서 ChatMessage에 한글을 추가해서 서버로 전송할 경우 다음과 같은 에러가 발생됩니다.

2020-07-31 16:56:42.579 ERROR 24230 --- [nio-8080-exec-8] o.s.w.s.m.StompSubProtocolHandler        : Failed to parse TextMessage payload=[SEND
conte..], byteCount=169, last=true] in session 1c5e7003-3678-afaa-5410-a2fb51e5103a. Sending STOMP ERROR to client.
​
org.springframework.messaging.simp.stomp.StompConversionException: Frame must be terminated with a null octet
	at org.springframework.messaging.simp.stomp.StompDecoder.readPayload(StompDecoder.java:313) ~[spring-messaging-5.1.3.RELEASE.jar:5.1.3.RELEASE]
	at org.springframework.messaging.simp.stomp.StompDecoder.decodeMessage(StompDecoder.java:147) ~[spring-messaging-5.1.3.RELEASE.jar:5.1.3.RELEASE]
	at org.springframework.messaging.simp.stomp.StompDecoder.decode(StompDecoder.java:114) ~[spring-messaging-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    ....

 

 

해결 : StompMessage.cs 의 다음의 this["content-length"]부분은 수정해줘야 합니다.

        /// <param name = "command">The command.</param>
        /// <param name = "body">The body.</param>
        /// <param name = "headers">The headers.</param>
        internal StompMessage(string command, string body, Dictionary<string, string> headers)
        {
            Command = command;
            Body = body;
            _headers = headers;

            //this["content-length"] = body.Length.ToString();
            this["content-length"] = Encoding.UTF8.GetByteCount(body).ToString();
        }

      영문을 송수신할때는 문제가 없지만 한글을 송수신할때는 this["content-length"]의 byte길이가 정확하지 않게 세팅되어서 서버에서 TextMessage를 분석하는데 에러를 발생합니다. 생각보다 간단하고 이해할 수 있는 부분이지만 처음 접하는 부분이라 며칠 고생을 했습니다. 그리고 최근에는 너무 좋은 서비스들이 많아서 그런지 앱 서비스 개발시 직접 구현하는 분들이 별로 없는것 같습니다. 월 십몇만원이면 5~600CCU 정도를 지원하는 서비스를 운영할 수 있으니 검증된 서비스를 이용하는게 어떻게 보면 글로벌 서비스를 위해서 리스크를 최소화할 수 있는것 같습니다. 

     하지만 가끔 직접 개발을 해야 할때가 있습니다. 저는 통합 관리 도구와 연동을 편하게 하기위해서 직접 네트워크 서버를 개발해서 사용할 계획 입니다. 동접자와 서비스의 안정화를 어느정도 보장되는지를 확인해봐야 하겠지만 지금 생각으로는 글로벌 서비스에 충분히 활용할 수 있을것으로 생각됩니다.

 

Server에서 사용한 기술들 :
1. Spring 
2. Websocket
3. STOMP

 

Client에서 사용한 기술들 : 

1. Unity3D C#

2. WebSocketSharp (https://github.com/sta/websocket-sharp)

3. StompHelper (https://github.com/huhuhong/websocket-csharp-net-stomp-client)

 

Unity C#의 Client부분의 사용 예는 다음과 같습니다. 

ChatMessage.cs

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using static AMPlusSDK.GlobalDefine;

[System.Serializable]
public class ChatMessage
{
    public MessageType type;
    public string content;
    public string sender;

    public MessageType Type
    {
        set
        {
            type = value;
        }
        get
        {
            return type;
        }
    }

    public string Content
    {
        set
        {
            content = value;
        }
        get
        {
            return content;
        }
    }

    public string Sender
    {
        set
        {
            sender = value;
        }
    }
}

사용 예 : 

void ConnectChatServer()
{
	....
	websocket = new WebSocket("ws://192.168.0.21:8080/chat");
	....
}

void DoChat()
{
	....
    StompMessageSerializer serializer = new StompMessageSerializer();
    
    ChatMessage chatMsg = new ChatMessage()
    {
    	Type = GlobalDefine.MessageType.CHAT,
    	Sender = "cookzy",
    	Content = "Hello, 안녕."
    };
    string json = JsonUtility.ToJson(chatMsg);                

	var broad = new StompMessage(StompFrame.SEND, json);
	broad["content-type"] = "application/json;charset=utf-8";
	broad["id"] = "sub-" + clientId;
	broad["destination"] = "/app/chat.sendMessage";

	websocket.Send(serializer.Serialize(broad));    
    ....
}

 

728x90
반응형