websocket:如何建立在同一台client和同一台server创建多个连接

最近一直纠结到底能不能在同一台服务器上和同一个客户端建立多个通讯连接,经过查阅大量的网页资料+亲自实践证明确实可以这样做,但是他们如何通讯?下面是相关代码:

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执行效果图
client执行返回结果

11> 建立第一条连接:
“Jhon comeback… & Phonenumber is 132132132132132”是初始化后server返回的”
22> 建立第二条连接:
“hello comeback… & Phonenumber is 13713713737137”是输入“hello 13713713737137 ”的返回

谨以此记录一下这个的坑

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值