WebSocket 및 FastapI를 사용한 간단한 채팅 애플리케이션

18704 단어 pythonwebsocketfastapi
최초 발표자 blog
여보게, 친구들, 나는 또Fast API를 수리하고 있어.이번에 나는 매우 간단한 채팅 웹 응용 프로그램을 구축하려고 시도할 것이다.FastapI에서 WebSocket을 사용할 예정입니다.
Websockets의 완전한 해석은 전체 문장을 필요로 하기 때문에 나는 독자가 이 협의에 대해 어느 정도 알고 있다고 가정한다.이것은 협의 자체가 아니라 HTTP의 업그레이드와 같다.
또 하나 지적해야 할 것은 내가 FastAPI 문서로 해킹한 결과다.그래서 나는 더 좋은 방법을 깊이 가르치지 못했다.다른 한 편의 문장에서, 나는 너에게 이 문제를 해결하기 위해 더욱 성숙한 방법을 소개할 것이다.이제 우리 공부의 즐거움을 누리자.

우리는 무엇을 만들고 싶습니까?부분 수요 설명.
인코딩을 시작하기 전에 우리가 무엇을 하고 싶은지 생각해 봅시다.이 아이디어는 간단한 홈페이지를 만들어 채팅방의 행동을 모의하는 것이다.
원하는 동작:
  • 브라우저에서 페이지를 엽니다.
  • 같은 URL에 연결되어 있지만 다른 브라우저를 통해 모든 클라이언트가 대화할 수 있습니다.

  • 행위의 기본 설계
    Client1과 Client2는 ishttp://localhost:8000와 같은 URL에 연결됩니다.연결이 완료되면 Client1의 각 메시지가 룸에 연결된 다른 클라이언트로 브로드캐스트됩니다. 이 경우 Client2가 됩니다.따라서 모델에 대한 전체적인 견해는 ASCII 그림과 같습니다.
    
       Client 1
    
         ___T_                              SERVER (FastAPI)
        | O O |                             +---------+
        |__n__|           Message 1         |         |
     >===]__o[===<    --------------->      |         |
         [o__]            Message 2         |         |
         ]| |[        <--------------       |         |
        [_| |_]                             |         |
                                            |         |
                                            |         | 
       Client 2                             |         |
                                            |         |
         ___T_                              |         |
        | O O |                             |         |
        |__n__|          Message 2          |         |
     >===]__o[===<   --------------->       |         |
         [o__]           Message 1          |         |
         ]| |[       <--------------        |         |
        [_| |_]                             +---------+
    
    

    Robot ascii generated with go-asciibot


    클라이언트 1은 서버에 메시지를 보내고 서버는 방의 다른 클라이언트에게 메시지를 방송한다.

    요구 사항
  • FastAPI
  • $ pip install fastapi
    
  • 우비콘
  • $ pip install uvicorn
    

    서버 코드
    코드에 뛰어들래요.나는 그것을 두 부분으로 나눌 것이다. 한 부분은 서버 코드이고, 다른 한 부분은 클라이언트 코드이다.
    앞에서 말한 바와 같이, HTML 페이지를 서비스할 단점이 필요합니다. 이 예에는 클라이언트 코드가 포함되어 있습니다.그래서 우리는 FastapI를 사용하여 HTML을 제공하는 방법을 배워야 한다.HTML 코드는 파일index.html에 있고 파일main.py과 같은 폴더에 있습니다.
    
    from fastapi import FastAPI
    
    app = FastAPI()
    
    html = ""
    with open('index.html', 'r') as f:
        html = f.read()
    
    @app.get("/")
    async def get():
        return HTMLResponse(html)
    
    그럼 여기 무슨 일이 일어났어요?우선, 프로그램을 만들 수 있도록 FastapI 클래스를 간단하게 가져옵니다.다음에 우리는 index.html 파일의 내용을 읽고 그 내용을 html이라는 변수에 저장한다.반드시 더 좋은 방법이 이 점을 해낼 수 있을 것이다. 그러나 우리에게 있어서 그것은 우리의 문제를 해결했다.
    HTML 파일의 내용이 무엇인지 알고 싶을 수도 있으니 우리가 볼 테니 걱정하지 마세요.
    마지막으로 우리는 색인에 접근할 수 있는 단점을 정의했다.html 파일.이렇게 하면 http://localhost:8000에 액세스하면 브라우저에 HTML이 표시됩니다.
    그럼 다음은요?지금까지 우리는 HTML의 내용만 보여줄 수 있었지만, 우리는 아직 다른 상황을 처리하지 못했다. 그렇지?우리는 어떻게 한 고객과 다른 고객을 구분합니까?우리가 이 문제를 해결합시다.
    from typing import List
    from fastapi import FastAPI, WebSocket
    from fastapi.responses import HTMLResponse
    
    class ConnectionManager:
        def __init__(self):
            self.connections: List[WebSocket] = []
    
        async def connect(self, websocket: WebSocket):
            await websocket.accept()
            self.connections.append(websocket)
    
        async def broadcast(self, data: str):
            for connection in self.connections:
                await connection.send_text(data)
    
    
    manager = ConnectionManager()
    
    
    @app.websocket("/ws/{client_id}")
    async def websocket_endpoint(websocket: WebSocket, client_id: int):
        await manager.connect(websocket)
        while True:
            data = await websocket.receive_text()
            await manager.broadcast(f"Client {client_id}: {data}")
    
    말 그대로 ConnectionManager라는 클래스는 서로 다른 클라이언트 연결을 처리하는 클래스입니다.
  • 이 클래스의 connect 방법은Websocket 클라이언트를 매개 변수로 한다.이 클라이언트는 브라우저로부터 메시지를 받아들여 모든 클라이언트와 목록에 추가합니다.
  • broadcast 방법을 매개 변수 amessage로 하고 그 내용을 방의 다른 고객에게 방송한다.
  • 각 클라이언트는 http://localhost:8000/ws/{client_id}에 연결됩니다. 여기서 {client_id}는 클라이언트를 식별하는 정수입니다.연결된 후 브라우저로부터 메시지를 받기 시작합니다.
    이 정보 중 어느 것이든 잠시 후에 방안의 모든 고객에게 방송될 것이다.

    클라이언트 코드
    이제 클라이언트 코드를 봅시다. 우리의 예는 HTML 코드입니다.
    
    <!DOCTYPE html>
    <html>
        <head>
            <title>Chat</title>
        </head>
        <body>
            <h1>WebSocket Chat</h1>
            <button onClick="showForm(event)" id="connect">Connect</button>
            <form action="" onsubmit="sendMessage(event)" id="form" style="display: none">
                <input type="text" id="messageText" autocomplete="off"/>
                <button>Send</button>
            </form>
            <ul id='messages'>
            </ul>
            <script>
                var clientID = Date.now();
                var ws = new WebSocket(`ws://localhost:8000/ws/${clientID}`);
    
                function processMessage(event) {
                    var messages = document.getElementById('messages')
                    var message = document.createElement('li')
                    var content = document.createTextNode(event.data)
                    message.appendChild(content);
                    messages.appendChild(message);
                }
    
                ws.onmessage = processMessage;
    
                function sendMessage(event) {
                    var input = document.getElementById("messageText")
                    var message = document.createElement('li')
                    var content = document.createTextNode(input.value)
                    message.appendChild(content);
                    messages.appendChild(message);
                    ws.send(input.value);
    
                    input.value = ''
                    event.preventDefault()
                }
    
                function showForm(event) {
                    var button = document.getElementById("connect");
                    var form = document.getElementById("form");
                    button.style.display = "none";
                    form.style.display = "block";
                }
    
            </script>
        </body>
    </html>
    
    
    무정전 전원!!이것은 대량의 정보이기 때문에 우리는 그것을 블록으로 나누고 적어도 가장 중요한 부분을 이해하려고 시도한다.일반 HTML에는 두 개의 주요 구성 요소가 있는데, 폼과 단추가 있다.
  • 버튼을 누릅니다.버튼을 클릭하면 클라이언트에 숨겨지고 폼이 보입니다.그냥 수작 부리지 마.이것은 javascript 방법으로 showForm를 통해 완성된 것이다.
  • 이 폼은 메시지를 쓰기 위한 입력 필드와 send 단추를 포함하고 이 단추는 자바스크립트 쪽을 촉발하는 방법sendMessage을 포함한다.
  • send 단추를 누르면 Websocket 연결을 사용하여 텍스트를 서버에 보냅니다.이렇게 하면 서버가 메시지를 받았을 때, 서버는 그것을 방안의 다른 클라이언트에게 방송할 것이다.

    어떻게 그것을 운행합니까?
    uvicorn main:app --reload
    
    --reload 로고는 고장 시 복구할 수 있어 매우 유용하다.
    이것이 바로 모든 사람들이다. 나는 틀림없이 나의 작문 기술을 향상시켜야 할 것이다. 동시에 나는 계속 연습할 것이다.

    테스트 애플리케이션
    최소 두 개의 웹 브라우저를 열고 연결 localhost:8000

    좋은 웹페이지 즐겨찾기