最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

GO使用socket和channel實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)聊天室

 更新時(shí)間:2021年12月20日 16:00:45   作者:謙虛的小學(xué)徒  
今天小編給大家分享一個(gè)簡(jiǎn)單的聊天室功能,聊天室主要功能是用戶(hù)可以加入離開(kāi)聊天室,實(shí)現(xiàn)思路也很簡(jiǎn)單明了,下面小編給大家?guī)?lái)了完整代碼,感興趣的朋友跟隨小編一起看看吧

使用socket和channel,實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)聊天室

這里使用socket和channel,演示在GO中如何編寫(xiě)一個(gè)簡(jiǎn)單網(wǎng)絡(luò)程序

功能分析

聊天室主要功能:用戶(hù)可以加入/離開(kāi)聊天室;每個(gè)用戶(hù)發(fā)送的消息,廣播給所有人
聊天室分為客戶(hù)端和服務(wù)端,客戶(hù)端負(fù)責(zé)發(fā)送消息和打印服務(wù)器消息,服務(wù)器負(fù)責(zé)接收客戶(hù)端消息,并廣播給所有人
客戶(hù)端可以使用telnet程序
服務(wù)端是需要實(shí)現(xiàn)的。需要實(shí)現(xiàn)的功能,

  1. 如何保存多個(gè)客戶(hù)端的連接,管理連接的接入與斷開(kāi)
  2. 如何接收和廣播客戶(hù)端消息

實(shí)現(xiàn)思路

通過(guò)功能分析,拆分為聊天室結(jié)構(gòu)體和客戶(hù)端結(jié)構(gòu)體
聊天室結(jié)構(gòu)體負(fù)責(zé)管理當(dāng)前接入的客戶(hù)端和廣播消息
客戶(hù)端結(jié)構(gòu)體負(fù)責(zé)管理socket連接和需要接收與發(fā)送的數(shù)據(jù)
客戶(hù)端連接/斷開(kāi)時(shí)通知聊天室;客戶(hù)端發(fā)送的消息實(shí)際是轉(zhuǎn)發(fā)給聊天室,然后聊天室再?gòu)V播出去

完整代碼

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()
	}
}

分析

實(shí)現(xiàn)的關(guān)鍵是封裝了客戶(hù)端通信channel,無(wú)論是遠(yuǎn)程發(fā)送過(guò)來(lái)的消息還是聊天室廣播的消息,都通過(guò)這個(gè)channel傳遞,且這個(gè)channel是綁定客戶(hù)端的
參考鏈接中,直接使用channel來(lái)定義客戶(hù)端type client chan<- string,其實(shí)更能表達(dá)這一點(diǎn)
為了容易理解,這里將channel封裝為客戶(hù)端的一個(gè)通信管道,客戶(hù)端還可以有別的屬性,例如:id、連接和超時(shí)時(shí)間等

參考: Go 網(wǎng)絡(luò)編程示例

到此這篇關(guān)于GO實(shí)現(xiàn)簡(jiǎn)單控制臺(tái)聊天室的文章就介紹到這了,更多相關(guān)go控制臺(tái)聊天室內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文帶你了解Go語(yǔ)言實(shí)現(xiàn)的并發(fā)神庫(kù)conc

    一文帶你了解Go語(yǔ)言實(shí)現(xiàn)的并發(fā)神庫(kù)conc

    前幾天逛github發(fā)現(xiàn)了一個(gè)有趣的并發(fā)庫(kù)-conc,這篇文章將為大家詳細(xì)介紹一下這個(gè)庫(kù)的實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的可以了解一下
    2023-01-01
  • 從生成CRD到編寫(xiě)自定義控制器教程示例

    從生成CRD到編寫(xiě)自定義控制器教程示例

    這篇文章主要為大家介紹了從生成CRD到編寫(xiě)自定義控制器的教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 詳解Go?中的時(shí)間處理

    詳解Go?中的時(shí)間處理

    這篇文章主要介紹了Go?中的時(shí)間處理,本文將介紹?time?庫(kù)中一些重要的函數(shù)和方法,希望能幫助到那些一遇到?Go?時(shí)間處理問(wèn)題就需要百度的童鞋,需要的朋友可以參考下
    2022-07-07
  • 簡(jiǎn)單四步快速集成go環(huán)境變量

    簡(jiǎn)單四步快速集成go環(huán)境變量

    這篇文章主要為大家介紹了快速集成go環(huán)境變量的簡(jiǎn)單四個(gè)步驟詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • go?mode?tidy出現(xiàn)報(bào)錯(cuò)go:?warning:?“all“?matched?no?packages的解決方法

    go?mode?tidy出現(xiàn)報(bào)錯(cuò)go:?warning:?“all“?matched?no?package

    使用go的時(shí)候我們一般都會(huì)使用go?mode管理,下面這篇文章主要給大家介紹了關(guān)于go?mode?tidy出現(xiàn)報(bào)錯(cuò)go:?warning:?“all“?matched?no?packages的解決方法,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • go實(shí)現(xiàn)自動(dòng)復(fù)制U盤(pán)小工具demo

    go實(shí)現(xiàn)自動(dòng)復(fù)制U盤(pán)小工具demo

    這篇文章主要為大家介紹了go實(shí)現(xiàn)自動(dòng)復(fù)制U盤(pán)小工具demo,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Golang?RPC的原理與簡(jiǎn)單調(diào)用詳解

    Golang?RPC的原理與簡(jiǎn)單調(diào)用詳解

    RPC(Remote?Procedure?Call),主要是幫助我們屏蔽網(wǎng)絡(luò)編程細(xì)節(jié)?,使我們更專(zhuān)注于業(yè)務(wù)邏輯,所以本文主要來(lái)和大家聊聊RPC的原理與簡(jiǎn)單調(diào)用,希望對(duì)大家有所幫助
    2023-05-05
  • Go語(yǔ)言fmt模塊的完整方法詳解及示例代碼

    Go語(yǔ)言fmt模塊的完整方法詳解及示例代碼

    這篇文章主要介紹了Go語(yǔ)言fmt模塊使用的相關(guān)資料,fmt庫(kù)最基本的功能之一就是格式化輸出,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2025-03-03
  • golang?gorm的Callbacks事務(wù)回滾對(duì)象操作示例

    golang?gorm的Callbacks事務(wù)回滾對(duì)象操作示例

    這篇文章主要為大家介紹了golang?gorm的Callbacks事務(wù)回滾對(duì)象操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • Go中的字典Map增刪改查、排序及其值類(lèi)型

    Go中的字典Map增刪改查、排序及其值類(lèi)型

    本文詳細(xì)介紹了Go語(yǔ)言中Map的基本概念、聲明初始化、增刪改查操作、反轉(zhuǎn)、排序以及如何判斷鍵是否存在等操作,Map是一種基于鍵值對(duì)的無(wú)序數(shù)據(jù)結(jié)構(gòu),鍵必須是支持相等運(yùn)算符的類(lèi)型,值可以是任意類(lèi)型,初始化Map時(shí)推薦指定容量以提高性能
    2024-09-09

最新評(píng)論

天长市| 肃南| 长宁区| 屏山县| 安达市| 凤凰县| 明星| 伊金霍洛旗| 正蓝旗| 定陶县| 沂水县| 盐源县| 内江市| 墨脱县| 乌兰县| 东乌| 黑河市| 印江| 阿勒泰市| 丰镇市| 保靖县| 崇明县| 明星| 平江县| 盐津县| 临高县| 潮州市| 襄樊市| 徐汇区| 米脂县| 芦溪县| 康保县| 墨脱县| 白城市| 开封县| 泸水县| 永嘉县| 公安县| 庐江县| 杨浦区| 保康县|