Golang GO와 마이크로서비스 ChatServer 1

4064 단어 golang

인연


최근 읽기<>(유금량, 2021.1) 본 시리즈 노트는 golang으로 연습할 예정

케이스 요구사항(채팅 서버)

  • 사용자는 서버에 연결할 수 있습니다..
  • 사용자는 자신의 사용자 이름을 설정할 수 있습니다..
  • 사용자는 서버에 메시지를 보낼 수 있고 서버도 다른 사용자에게 이 메시지를 방송할 수 있다..

  • 목표

  • 통신 프로토콜을 정의하는데 신호 정의, 코딩 실현을 포함한다
  • 채팅 클라이언트(시간에 제한이 있고 채팅 서비스 단말기를 후속적으로 실현하고 테스트)

  • 설계

  • IMsg: 메시지 인터페이스를 정의하고 관련 메시지의 실현.임의의 메시지 내용의 디코딩을 편리하게 하기 위해, 메시지 전송 시,base64 디코딩을 사용합니다
  • IMsgDecoder: 메시지 디코더와 그 실현을 정의합니다
  • IChatClient: 채팅 클라이언트 인터페이스를 정의합니다
  • tChatClient: 채팅 클라이언트, IChatClient 인터페이스 실현
  • IChatServer: 아직 완성되지 않았습니다
  • tChatServer: 아직 완료되지 않았습니다

  • IMsg.go


    메시지 인터페이스를 정의하고 관련 메시지의 실현을 정의합니다.임의의 메시지 내용의 디코딩을 편리하게 하기 위해, 메시지 전송 시,base64 디코딩을 사용한다
    package chat_server
    
    import (
        "encoding/base64"
        "fmt"
    )
    
    type IMsg interface {
        Encode() string
    }
    
    type NameMsg struct {
        Name string
    }
    
    func (me *NameMsg) Encode() string {
        return fmt.Sprintf("NAME %s", base64.StdEncoding.EncodeToString([]byte(me.Name)))
    }
    
    type ChatMsg struct {
        Name string
        Words string
    }
    
    func (me *ChatMsg) Encode() string {
        return fmt.Sprintf("CHAT %s %s",
            base64.StdEncoding.EncodeToString([]byte(me.Name)),
            base64.StdEncoding.EncodeToString([]byte(me.Words)),
        )
    }

    IMsgDecoder.go


    메시지 디코더 및 그 실현 정의
    package chat_server
    
    import (
        "encoding/base64"
        "strings"
    )
    
    
    type IMsgDecoder interface {
        Decode(line string) (bool, IMsg)
    }
    
    type tMsgDecoder struct {
    }
    
    func (me *tMsgDecoder) Decode(line string) (bool, IMsg) {
        items := strings.Split(line, " ")
        size := len(items)
    
        if items[0] == "NAME" && size == 2 {
            name, err := base64.StdEncoding.DecodeString(items[1])
            if err != nil {
                return false, nil
            }
    
            return true, &NameMsg{
                Name: string(name),
            }
        }
    
        if items[0] == "CHAT" && size == 3 {
            name, err := base64.StdEncoding.DecodeString(items[1])
            if err != nil {
                return false, nil
            }
    
            words, err := base64.StdEncoding.DecodeString(items[2])
            if err != nil {
                return false, nil
            }
    
            return true, &ChatMsg{
                Name: string(name),
                Words: string(words),
            }
        }
    
        return false, nil
    }
    
    
    var MsgDecoder = &tMsgDecoder{}

    IChatClient.go


    채팅 클라이언트 인터페이스 정의
    package chat_server
    
    type IChatClient interface {
        Dial(address string) error
        Send(msg IMsg)
        RecvHandler(handler RecvFunc)
        Close()
    }
    
    type RecvFunc func(msg IMsg)

    tChatClient.go


    채팅 클라이언트, IChatClient 인터페이스 구현
    package chat_server
    
    import (
        "bufio"
        "net"
        "sync/atomic"
    )
    
    type tChatClient struct {
        conn net.Conn
        closeFlag int32
    
        closeChan chan bool
        sendChan chan IMsg
    
        name string
        sendLogs []IMsg
        recvLogs []IMsg
        recvHandler RecvFunc
    }
    
    func DialChatClient(address string) (error, IChatClient) {
        it := &tChatClient{
            conn: nil,
            closeFlag: 0,
    
            closeChan: make(chan bool),
            sendChan: make(chan IMsg),
    
            name: "anonymous",
            sendLogs: []IMsg{},
            recvLogs: []IMsg{},
        }
    
        e := it.Dial(address)
        if e != nil {
            return e, nil
        }
    
        return nil, it
    }
    
    func (me *tChatClient) Dial(address string) error {
        c, e := net.Dial("tcp", address)
        if e != nil {
            return e
        }
        me.conn = c
    
        go me.beginWrite()
        go me.beginRead()
    
        return nil
    }
    
    
    func (me *tChatClient) isClosed() bool {
        return me.closeFlag != 0
    }
    
    func (me *tChatClient) isNotClosed() bool {
        return !me.isClosed()
    }
    
    func (me *tChatClient) Send(msg IMsg) {
        if me.isNotClosed() {
            me.sendChan 

    (미완성 미계속)

    좋은 웹페이지 즐겨찾기