中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

GO使用socket和channel怎么實現簡單控制臺聊天室

發布時間:2021-12-20 21:23:12 來源:億速云 閱讀:152 作者:柒染 欄目:開發技術

今天就跟大家聊聊有關GO使用socket和channel怎么實現簡單控制臺聊天室,可能很多人都不太了解,為了讓大家更加了解,小編給大家總結了以下內容,希望大家根據這篇文章可以有所收獲。

使用socket和channel,實現簡單控制臺聊天室

這里使用socket和channel,演示在GO中如何編寫一個簡單網絡程序

功能分析

聊天室主要功能:用戶可以加入/離開聊天室;每個用戶發送的消息,廣播給所有人
聊天室分為客戶端和服務端,客戶端負責發送消息和打印服務器消息,服務器負責接收客戶端消息,并廣播給所有人
客戶端可以使用telnet程序
服務端是需要實現的。需要實現的功能,

  1. 如何保存多個客戶端的連接,管理連接的接入與斷開

  2. 如何接收和廣播客戶端消息

實現思路

通過功能分析,拆分為聊天室結構體和客戶端結構體
聊天室結構體負責管理當前接入的客戶端和廣播消息
客戶端結構體負責管理socket連接和需要接收與發送的數據
客戶端連接/斷開時通知聊天室;客戶端發送的消息實際是轉發給聊天室,然后聊天室再廣播出去

完整代碼

package main

import (
	"bufio"
	"fmt"
	"log"
	"net"
)

type Client struct {
	id      string
	conn    *net.Conn
	message chan string
}

type Hub struct {
	clients  map[*Client]bool
	entering chan *Client
	leaving  chan *Client
	messages chan string
}

func main() {
	hub := &Hub{
		clients:  make(map[*Client]bool),
		entering: make(chan *Client),
		leaving:  make(chan *Client),
		messages: make(chan string),
	}

	listener, err := net.Listen("tcp", ":8000")
	if err != nil {
		log.Fatal(err)
	}
	go hub.broadcaster()
	for {
		conn, err := listener.Accept()
		if err != nil {
			log.Println(err)
			continue
		}
		go hub.handleConn(conn)
	}
}

func (hub *Hub) broadcaster() {
	for {
		select {
		case msg := <-hub.messages:
			for cli := range hub.clients {
				cli.message <- msg
			}
		case cli := <-hub.entering:
			hub.clients[cli] = true
		case cli := <-hub.leaving:
			delete(hub.clients, cli)
		}
	}
}

func (hub *Hub) handleConn(conn net.Conn) {
	defer conn.Close()
	ch := make(chan string)
	who := conn.RemoteAddr().String()
	client := &Client{who, &conn, ch}

	go hub.writeLoop(client)
	ch <- "welcome " + client.id

	hub.messages <- client.id + " join chat"
	hub.entering <- client
	hub.readLoop(client)
	hub.messages <- client.id + " has left"
	hub.leaving <- client
}

func (hub *Hub) writeLoop(client *Client) {
	for msg := range client.message {
		fmt.Fprintf(*client.conn, "%s\n", msg)
	}
}

func (hub *Hub) readLoop(client *Client) {
	input := bufio.NewScanner(*client.conn)
	for input.Scan() {
		hub.messages <- client.id + ": " + input.Text()
	}
}

分析

實現的關鍵是封裝了客戶端通信channel,無論是遠程發送過來的消息還是聊天室廣播的消息,都通過這個channel傳遞,且這個channel是綁定客戶端的
參考鏈接中,直接使用channel來定義客戶端type client chan<- string,其實更能表達這一點
為了容易理解,這里將channel封裝為客戶端的一個通信管道,客戶端還可以有別的屬性,例如:id、連接和超時時間等

看完上述內容,你們對GO使用socket和channel怎么實現簡單控制臺聊天室有進一步的了解嗎?如果還想了解更多知識或者相關內容,請關注億速云行業資訊頻道,感謝大家的支持。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长兴县| 南京市| 崇义县| 德格县| 赫章县| 平遥县| 平湖市| 博客| 伊川县| 温宿县| 宜春市| 华安县| 太原市| 清水河县| 龙泉市| 明光市| 景东| 衡水市| 三门峡市| 铁力市| 翁源县| 车致| 苏尼特左旗| 资阳市| 乌拉特后旗| 成都市| 阿克苏市| 翼城县| 东台市| 库尔勒市| 岱山县| 晋州市| 琼中| 雅安市| 神农架林区| 稻城县| 寿宁县| 策勒县| 龙门县| 崇礼县| 延安市|