Goチャットルーム(goroutine)
前言
無名先生のgoroutineとchannelについての説明授業を見て、よく分からなかったので、チャットルームの機能を実現することにしました.
どうしてグループチャットなの?
グループチャットは論理的に簡単だから
注:本栗はgoroutineにしか使われておらずchannelには使われていません
概要
1.チャットルームの構成
チャットルームは2つの部分に分かれています.それぞれ:サービス側 クライアント そして、一般的にはお互いにチャットしているのはクライアントだけで、サービス側はスケジューリングの役割を果たしているだけです.
2.情報の送受信の流れ
理論上の流れはこうです.C 1はSにメッセージを送信 S受信情報 S受信した情報をC 2 C 3 にブロードキャストするC 2 C 3受信情報 じっこう
1.サービス側
1)コード
b)説明
main関数を除いて、2つのroutineがあります.それぞれ:傍受接続 受信メッセージ(ブロードキャストメッセージもここにある) 2.クライアント
a)コード
b)説明
同様に、クライアントにも2つのroutineがあります.メッセージ受信機 メッセージ送信機 プライマリ・スレッドでの接続の確立
3.効果図
a)サービス側
b)クライアント_1
c)クライアント_2
の最後の部分
ここではチャンネルは使われていません
小栗は経験をまとめ、交流を学ぶためだけに覚えています.
無名先生のgoroutineとchannelについての説明授業を見て、よく分からなかったので、チャットルームの機能を実現することにしました.
どうしてグループチャットなの?
グループチャットは論理的に簡単だから
注:本栗はgoroutineにしか使われておらずchannelには使われていません
概要
1.チャットルームの構成
チャットルームは2つの部分に分かれています.それぞれ:
2.情報の送受信の流れ
(S)
(C1)
(C2)
(C3)
SはC 1 C 2 C 3と接続されている理論上の流れはこうです.
1.サービス側
1)コード
package main
import (
"time"
"fmt"
"net"
)
// map
var client_map = make(map[string]*net.TCPConn)
//
func listen_client(ip_port string) {
tcpAddr, _ := net.ResolveTCPAddr("tcp", ip_port)
tcpListener, _ := net.ListenTCP("tcp", tcpAddr)
for {//
client_con, _ := tcpListener.AcceptTCP()//
client_map[client_con.RemoteAddr().String()] = client_con// map
go add_receiver(client_con)
fmt.Println(" : ", client_con.RemoteAddr().String(), " .")
}
}
//
func add_receiver(current_connect *net.TCPConn) {
for {
byte_msg := make([]byte, 2048)
len, err := current_connect.Read(byte_msg)
if err != nil { current_connect.Close() }
fmt.Println(string(byte_msg[:len]))
msg_broadcast(byte_msg[:len], current_connect.RemoteAddr().String())
}
}
// client
func msg_broadcast(byte_msg []byte, key string) {
for k, con := range client_map {
if k != key { con.Write(byte_msg) }
}
}
//
func main() {
fmt.Println(" ...")
time.Sleep(1 * time.Second)
fmt.Println(" ...")
go listen_client("127.0.0.1:1801")
select{}
}
b)説明
main関数を除いて、2つのroutineがあります.それぞれ:
a)コード
package main
import (
"fmt"
"net"
"os"
"bufio"
)
//
var login_name string
//
var self_connect *net.TCPConn
//
var reader = bufio.NewReader(os.Stdin)
//
func connect(addr string) {
tcp_addr, _ := net.ResolveTCPAddr("tcp", addr) // tcp
con, err := net.DialTCP("tcp", nil, tcp_addr) //
self_connect = con
if err != nil {
fmt.Println(" ")
os.Exit(1)
}
go msg_sender()
go msg_receiver()
}
//
func msg_receiver() {
buff := make([]byte, 2048)
for {
len, _ := self_connect.Read(buff) //
fmt.Println(string(buff[:len]))
}
}
//
func msg_sender() {
for {
read_line_msg, _, _ := reader.ReadLine()
read_line_msg = []byte(login_name + " : " + string(read_line_msg))
self_connect.Write(read_line_msg)
}
}
//
func main() {
fmt.Println(" ?")
name, _, _ := reader.ReadLine()
login_name = string(name)
connect("127.0.0.1:1801")
select{}
}
b)説明
同様に、クライアントにも2つのroutineがあります.
3.効果図
a)サービス側
b)クライアント_1
c)クライアント_2
の最後の部分
ここではチャンネルは使われていません
小栗は経験をまとめ、交流を学ぶためだけに覚えています.