Spring

Spring Boot + WebSocket + UDP 데이터 통신

주피터0410 2023. 7. 18. 17:10

C#으로 제작된 dummy 프로그램

WebSocket 클래스

1. @ServerEndpoint 설정

2. onMessage - UDP 데이터 송신

3. onClose - DatagramSocket close();

4. data - UDP 데이터 조합

package com.coforward.dev.controller;

import org.json.simple.JSONObject;
import org.springframework.stereotype.Service;
import org.springframework.web.socket.WebSocketSession;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.nio.ByteBuffer;
import java.util.HashMap;

@Service
@ServerEndpoint("/webSocket")
public class WebSocket {

    // 상대방이 연결할수 있도록 UDP 소켓 생성
    DatagramSocket socket;

    @OnMessage
    public void onMessage(String msg, Session session) throws Exception{
        JSONObject obj = new JSONObject();
        try {
            socket = new DatagramSocket(9047);

            // 전송받은 데이터를 지정할 바이트 배열선언
            byte[] receive = new byte[156];

            DatagramPacket packet = null;
            System.out.println("데이터 수신 준비 완료....");

            while (true) {
                // UDP 통신으로 전송을 받을 packet 객체생성
                packet = new DatagramPacket(receive, receive.length);

                // 데이터 전송 받기
                socket.receive(packet);

                obj = data(receive);
                session.getBasicRemote().sendText(obj.toString());
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

    @OnOpen
    public void onOpen(Session session) {
    }

    @OnClose
    public void onClose(Session session){
        socket.close();
    }

    @OnError
    public void onError(Throwable thr) {
        System.out.println(thr);
    }

    public static JSONObject data(byte[] a) {
        JSONObject obj = new JSONObject();

        // 데이터 길이
        int[] arr = { 4, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 4, 4 };
        // 데이터를 읽고 쓰는 방향(빅 엔디안(Big-Endian)0과 리틀 엔디안(Little-Endian)1)
        int[] order = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
        // 데이터 타입(i:int, t:timestamp, d:double)
        String[] dtype = { "i", "t", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "d", "i", "i", "i", "i" };
        String[] arrN = { "StartStop", "TimeStamp", "Roll", "Pitch", "Yaw", "P", "Q", "R", "AX", "AY", "AZ", "GPSnor", "GPSeast", "GPSalt", "GPSspd", "Longspd", "Latspd", "GPShdg", "Ext1", "Ext2", "Ext3", "Ext4" };

        int b = 0;
        int sn = 0;
        for (String name : arrN) {
            StringBuilder builder = new StringBuilder();
            int n = 0;
            byte[] data = new byte[8];
            int dn = 0;
            if (order[b] == 1) { // 역방향
                for (int i = sn + arr[b] - 1; i >= sn; i--) {
                    builder.append(a[i] + " ");
                    data[dn] = a[i];
                    dn++;
                }
            } else { // 정방향
                for (int i = sn; i < sn + arr[b]; i++) {
                    builder.append(a[i] + " ");
                }
            }

            if (dtype[b].equals("d")) { // 데이터 형식
                double value = Double.longBitsToDouble(ByteBuffer.wrap(data).getLong());
                obj.put(name, value);
                System.out.println(name + " :: " + builder.toString() + " ------>>>> " + value);
                // System.out.println(name + " : " + value);
            } else if (dtype[b].equals("i")) {
                int value = ByteBuffer.wrap(data).getInt();
                obj.put(name, value);
                System.out.println(name + " :: " + builder.toString() + " ------>>>> " + value);
            } else {
                long value = ByteBuffer.wrap(data).getLong();
                obj.put(name, value);
                System.out.println(name + " :: " + builder.toString() + " ------>>>> " + value);
            }

            // System.out.println(name + " :: " + sn + " ------>>>> " + builder.toString());
            sn = sn + arr[b];
            b++;
        }
        System.out.println("");

        return obj;
    }
}

 

화면 html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>WebSocket</title>
</head>
<script src="https://code.jquery.com/jquery-3.7.0.js"></script>
<script>
    window.onload = function() {
        const webSocket = new WebSocket("ws://localhost:8080/webSocket");

        // 웹 소켓 연결 이벤트
        webSocket.onopen = function () {
            if (webSocket.readyState == 1) {
                const deviceNum = 1;
                webSocket.send(deviceNum);
            }
        };

        // 웹 소켓 메세지 수신
        webSocket.onmessage = function (event) {
            var msg = JSON.parse(event.data);

            $('#StartStop_val').text(msg.StartStop);
            $('#TimeStamp_val').text(msg.TimeStamp);
            $('#Roll_val').text(msg.Roll);
            $('#Pitch_val').text(msg.Pitch);
            $('#Yaw_val').text(msg.Yaw);
            $('#P_val').text(msg.P);
            $('#Q_val').text(msg.Q);
            $('#R_val').text(msg.R);
            $('#AX_val').text(msg.AX);
            $('#AY_val').text(msg.AY);
            $('#AZ_val').text(msg.AZ);
            $('#GPSnor_val').text(msg.GPSnor);
            $('#GPSeast_val').text(msg.GPSeast);
            $('#GPSalt_val').text(msg.GPSalt);
            $('#GPSspd_val').text(msg.GPSspd);
            $('#Longspd_val').text(msg.Longspd);
            $('#Latspd_val').text(msg.Latspd);
            $('#GPShdg_val').text(msg.GPShdg);
            $('#Ext1_val').text(msg.Ext1);
            $('#Ext2_val').text(msg.Ext2);
            $('#Ext3_val').text(msg.Ext3);
            $('#Ext4_val').text(msg.Ext4);
        };

        // 웹 소켓 연결 종료
        webSocket.onclose = function () {
            alert("웹소켓 서버와 연결이 종료되었습니다.");
        };

        // 오류 발생
        webSocket.onerror = function (error) {
            console.log(error);
        };
    }
</script>
<body>

<p><span>StartStop</span> : <span id="StartStop_val"></span></p>
<p><span>TimeStamp</span> : <span id="TimeStamp_val"></span></p>
<p><span>     Roll</span> : <span id="Roll_val"></span></p>
<p><span>    Pitch</span> : <span id="Pitch_val"></span></p>
<p><span>      Yaw</span> : <span id="Yaw_val"></span></p>
<p><span>        P</span> : <span id="P_val"></span></p>
<p><span>        Q</span> : <span id="Q_val"></span></p>
<p><span>        R</span> : <span id="R_val"></span></p>
<p><span>       AX</span> : <span id="AX_val"></span></p>
<p><span>       AY</span> : <span id="AY_val"></span></p>
<p><span>       AZ</span> : <span id="AZ_val"></span></p>
<p><span>   GPSnor</span> : <span id="GPSnor_val"></span></p>
<p><span>  GPSeast</span> : <span id="GPSeast_val"></span></p>
<p><span>   GPSalt</span> : <span id="GPSalt_val"></span></p>
<p><span>   GPSspd</span> : <span id="GPSspd_val"></span></p>
<p><span>  Longspd</span> : <span id="Longspd_val"></span></p>
<p><span>   Latspd</span> : <span id="Latspd_val"></span></p>
<p><span>   GPShdg</span> : <span id="GPShdg_val"></span></p>
<p><span>     Ext1</span> : <span id="Ext1_val"></span></p>
<p><span>     Ext2</span> : <span id="Ext2_val"></span></p>
<p><span>     Ext3</span> : <span id="Ext3_val"></span></p>
<p><span>     Ext4</span> : <span id="Ext4_val"></span></p>

</body>
</html>