고통은 사라지고 결과는 남는다. Records of Chansolve

외부 클라이언트 내부 서버에 연결 본문

Computer Science

외부 클라이언트 내부 서버에 연결

엄청큰노란닭 2023. 9. 20. 18:00

외부 클라이언트 -> 에코서버 & 웹소켓 서버 -> 웹소켓 클라이언트로 연결하는 프로그램을 만들었다..

너무 고생했다...

 

방화벽을 끄고 잘 해보자 ,,!!!!

import socket
import asyncio
import websockets
import threading

# 웹 소켓 클라이언트 목록을 저장하는 리스트
websocket_clients = []

# 에코 서버 함수
def echo_server():
    HOST = "~~"
    PORT = ~~
    # IPv4 체계, TCP 타입 소켓 객체를 생성
    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 소켓을 호스트와 포트에 바인딩
    server_socket.bind((HOST, PORT))
    # 클라이언트의 연결을 대기
    server_socket.listen()

    print(f"에코 서버가 {HOST}:{PORT}에서 대기 중...")

    while True:
        # 클라이언트의 연결을 수락
        client_socket, client_address = server_socket.accept()
        print(f"{client_address}가 연결되었습니다.")

        while True:
            # 외부 클라이언트로부터 받는 데이터
            data = client_socket.recv(1024)
            print(data.decode())

            # 데이터를 웹 소켓 클라이언트에 전송
            for ws_client in websocket_clients: # 리스트에 데이터를 보냄
                asyncio.run_coroutine_threadsafe(ws_client.send(data.decode()), ws_client.loop)

            # 외부에서 접속한 클라이언트로 보내는 데이터
            client_socket.send(data)

            if not data:
                break

        client_socket.close()
        print(f"{client_address}와의 연결이 종료되었습니다.")

# 웹 소켓 서버 함수
async def websocket_server(websocket, path):
    print(f"내부 클라이언트가 연결되었습니다.{path}")

    # 웹 소켓 클라이언트를 리스트에 추가
    websocket_clients.append(websocket)

    try:
        async for message in websocket:
            # 내부 클라이언트로 보냄
            await websocket.send(message)
    except websockets.ConnectionClosed: # 연결닫힘 예외처리
        pass
    finally:
        # 연결이 종료된 웹 소켓 클라이언트를 리스트에서 제거
        websocket_clients.remove(websocket)

# 메인 스레드에서 이벤트 루프 실행
if __name__ == "__main__":
    # 스레드로 에코 서버 실행
    echo_thread = threading.Thread(target=echo_server)
    echo_thread.start()

    # 웹소켓 서버 생성
    start_server = websockets.serve(websocket_server, ~~", ~~)

    # 비동기로 웹 소켓 서버 실행
    print(f"웹소켓서버가 ~:~에서 대기 중...")
    asyncio.get_event_loop().run_until_complete(start_server)
    asyncio.get_event_loop().run_forever()
<!DOCTYPE html>
<html>
<head>
    <title>WebSocket Data Display</title>
</head>
<body>
    <h1>WebSocket Data Display</h1>
    <div id="serveropen"></div>
    <div id="servernotopen"></div>
    <div id="message"></div>

    <script>
        // 웹 소켓 서버에 연결(내부)
        var socket = new WebSocket("ws://~~:~~/WebSocketClient");  // 웹 소켓 서버의 주소와 포트
    
        // 웹 소켓 연결이 열릴 때 실행되는 이벤트 리스너
        socket.onopen = function(event) {
            var serverOpenDiv = document.getElementById('serveropen');
            serverOpenDiv.innerHTML = '웹 소켓 서버와 연결되었습니다.';
            console.log("웹 소켓 서버와 연결되었습니다.");
        };
    
        // 웹 소켓 연결 에러 시 실행되는 이벤트 리스너
        socket.onerror = function(error) {
            var serverNotOpenDiv = document.getElementById('servernotopen');
            serverNotOpenDiv.innerHTML = '웹 소켓 서버 연결 실패: ' + error.message;
            console.error("웹 소켓 서버 연결 실패: " + error.message);
        };
    
        // 웹 소켓으로부터 메시지를 수신할 때 실행되는 이벤트 리스너
        socket.onmessage = function(event) {
            // 웹소켓에 들어온 데이터를 innerHTML에 추가
            var messageDiv = document.getElementById('message');
            
            // 새로운 메시지가 기존 메시지 아래에 추가
            // messageDiv.innerHTML += '<p>' + event.data + '</p>';

            // 새로운 메세지가 기존 메시지 상단에 추가
            messageDiv.insertAdjacentHTML('afterbegin', '<p>' + event.data + '</p>');

            console.log(event.data);
            console.log(messageDiv);
        };
    
        // 페이지를 닫을 때 웹 소켓 연결을 종료
        window.onbeforeunload = function() {
            socket.close();
        };
    </script>
    
</body>
</html>
Comments