最近一直纠结到底能不能在同一台服务器上和同一个客户端建立多个通讯连接,经过查阅大量的网页资料+亲自实践证明确实可以这样做,但是他们如何通讯?下面是相关代码:
Server.go 。。。。。。。。。。。。。。。。。。。。。。。。
package main
import (
"flag"
"fmt"
"log"
"net/http"
"github.com/gorilla/websocket"
"tttest/pubvisit"
"tttest/pubvisit/MapTable"
)
var upgrader = websocket.Upgrader{
ReadBufferSize: 4096,
WriteBufferSize: 4096,
}
func main() {
var addr = flag.String("addr", ":8000", "http service address")
http.HandleFunc("/Connection", Connection)
fmt.Println("Test Server Start...")
err := http.ListenAndServe(*addr, nil)
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
func Connection(w http.ResponseWriter, r *http.Request) {
conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
log.Println("Upgrade:", err)
}
defer conn.Close()
for {
info := pubvisit.ReadFromMsg(conn)
MapTable.SaveConn(conn, info.Name)
switch info.Name {
case "Jhon":
var jres pubvisit.Message
jres.Name = info.Name
jres.Phone = info.Phone
jres.Prompt = info.Name + " comeback..."
pubvisit.WriteReturnMsg(jres, conn)
default:
var ores pubvisit.Message
ores.Name = info.Name
ores.Phone = info.Phone
ores.Prompt = info.Name + " comeback..."
pubvisit.WriteReturnMsg(ores, conn)
}
}
}
Client.go 。。。。。。。。。。。。。。。。。。。。。。。。
package main
import (
"bufio"
"fmt"
"log"
"os"
"strings"
"time"
"tttest/pubvisit"
"tttest/pubvisit/MapTable"
"github.com/gorilla/websocket"
)
var visitAddr = "ws://127.0.0.1:8000/Connection"
func main() {
conn, _, err := websocket.DefaultDialer.Dial(visitAddr, nil)
if err != nil {
log.Fatal("dial:", err)
}
defer conn.Close()
MapTable.SaveConn(conn, "init") //保存创建的连接
pubvisit.InitData(conn) //发一个初始化包
go ClientWriterToSer()//开启一个goroutine提供写命令
for {
time.Sleep(1 * time.Second)
for key, rconn := range MapTable.ConnManage {
go func() { //goroutine 这里是第2条conn的监听处理
if !strings.EqualFold(key, "init") {
info2 := pubvisit.ReadFromMsg(rconn.Conn)
fmt.Println(info2.Prompt, " & Phonenumber is ", info2.Phone)
}
}()
}
// 下面是第1条conn的监听处理,会一直监听,这里不中断
fmt.Println("\n")
info := pubvisit.ReadFromMsg(conn)
fmt.Println(info.Prompt, " & Phonenumber is ", info.Phone)
fmt.Println("\n")
}
}
func ClientWriterToSer() {
for {
conn, _, err := websocket.DefaultDialer.Dial(visitAddr, nil)
if err != nil {
log.Fatal("dial:", err)
}
defer conn.Close()
MapTable.SaveConn(conn, "other")
var info pubvisit.Message
reader := bufio.NewReader(os.Stdin)
data, _, _ := reader.ReadLine()
reader2 := bufio.NewReader(os.Stdin)
data2, _, _ := reader2.ReadLine()
info.Name = string(data)
info.Phone = string(data2)
pubvisit.WriteReturnMsg(info, conn)
fmt.Println("") //在请求和响应之间加1个空格
}
}
tttest/pubvisit.go 。。。。。。。。。。。。。。。。。。。。。。。。
package pubvisit
import (
"encoding/json"
"fmt"
"log"
"tttest/pubvisit/HostInfo"
"github.com/gorilla/websocket"
)
type Message struct {
Name string `json:"name"`
Phone string `json:"phone"`
HostName string `json:"hostname"`
Prompt string `json:"prompt"`
}
func ReadFromMsg(Reconn *websocket.Conn) Message {
_, SerMsg, err := Reconn.ReadMessage()
if err != nil {
log.Println("read:", err)
}
var info Message
err = json.Unmarshal(SerMsg, &info)
if err != nil {
log.Println(err)
}
return info
}
func WriteReturnMsg(sbuf Message, conn *websocket.Conn) {
buffer, err := json.Marshal(sbuf)
if err != nil {
fmt.Println("error:", err)
}
err = conn.WriteMessage(websocket.TextMessage, buffer)
if err != nil {
fmt.Println("WriteMessage :", err)
}
}
func InitData(conn *websocket.Conn) {
name := "Jhon"
phone := "132132132132132"
hostname, _ := HostInfo.GetPcNameAndPcMac()
var msg Message
msg.Name = name
msg.Phone = phone
msg.HostName = hostname
WriteReturnMsg(msg, conn)
}
tttest/pubvisit/MapTable.go 。。。。。。。。。。。。。。。。。。。。。。。。
package MapTable
import (
"github.com/gorilla/websocket"
)
type Client struct {
Conn *websocket.Conn
}
var ConnManage = make(map[string]*Client)
func SaveConn(conn *websocket.Conn, subkey string) {
var cli Client
cli.Conn = conn
ConnManage[subkey] = &cli
}
tttest/pubvisit/HostInfo.go 。。。。。。。。。。。。。。。。。。。。。。。。
package HostInfo
import (
"log"
"net"
"os"
)
func GetPcNameAndPcMac() (HostName, HostMac string) {
//获取本机主机名
host, err := os.Hostname()
if err != nil {
log.Println(err)
} else {
HostName = host
}
// 获取本机的MAC地址
interfaces, err := net.Interfaces()
if err != nil {
panic("Poor soul, here is what you got: " + err.Error())
}
for _, inter := range interfaces {
// linux 环境下,第一个Mac接口为空,在此过滤,只取最优的
if inter.HardwareAddr.String() != "" {
macAddr := inter.HardwareAddr.String() //获取本机MAC地址
HostMac = macAddr
//fmt.Println("HostMac : ", HostMac)
break
}
}
return HostName, HostMac
}
1)编译执行server端代码
2)开始编译执行client端代码
3)client执行效果图
11> 建立第一条连接:
“Jhon comeback… & Phonenumber is 132132132132132”是初始化后server返回的”
22> 建立第二条连接:
“hello comeback… & Phonenumber is 13713713737137”是输入“hello 13713713737137 ”的返回
谨以此记录一下这个的坑