golang websocket demo

这篇博客介绍了如何使用Golang编写一个基本的WebSocket客户端demo,涵盖了连接建立、消息发送和接收的关键步骤,适合初学者了解Golang在WebSocket通信中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


package main

import (
   "fmt"
   "os"
   "golang.org/x/net/websocket"
   "net/http"
   "sync"
   "time"
   "log"
)

type Client struct {
   mu   sync.Mutex
   conn []*Conn
}

type Conn struct {
   conn      *websocket.Conn //客户端链接
   timeStamp int64          //加入时间
}

var Clients Client

func init() {
   Clients = Client{}

   //定时发送数据
// c := cron.New()
// c.AddFunc("0/10 * * * * ?", func() {
//    fmt.Println("定时器")
//    for _,client := range Clients.conn{
//       client.conn.Write([]byte("this is a check"))
//    }
// })
// c.Start()
}

//错误处理函数
func checkErr(err error, extra string) bool {
   if err != nil {
      formatStr := " Err : %s\n"
      if extra != "" {
         formatStr = extra + formatStr
      }

      fmt.Fprintf(os.Stderr, formatStr, err.Error())
      return true
   }

   return false
}
func svrConnHandler(conn *websocket.Conn) {
   request := make([]byte, 128)
   //记录连接的客户端信息
   Clients.mu.Lock()
   Clients.conn = append(Clients.conn, &Conn{
      conn:conn,
      timeStamp:time.Now().Unix(),
   })
   Clients.mu.Unlock()

   defer func(){
      log.Println("移除事件触发")
      for index,val := range Clients.conn{
         if val.conn == conn{
            Clients.mu.Lock()
            Clients.conn = Clients.conn[index:index+1]
         }
      }
      conn.Close()
   }()
   for {
      readLen, err := conn.Read(request)
      if checkErr(err, "Read") {
         break
      }
      //socket被关闭了
      if readLen == 0 {
         fmt.Println("Client connection close!")
         break
      } else {
         //request 可做口令 这里 输出接收到的信息
         fmt.Println(string(request[:readLen]))

         //回执客户端
         conn.Write([]byte("success"))
      }
      request = make([]byte, 128)
   }
}

func main() {
   http.Handle("/echo", websocket.Handler(svrConnHandler))
   err := http.ListenAndServe(":6666", nil)
   checkErr(err, "ListenAndServe")
   fmt.Println("Func finish.")

}

//client

package main

import (
"fmt"
"golang.org/x/net/websocket"
"os"
"sync"
)

var gLocker sync.Mutex    //全局锁
var gCondition *sync.Cond //全局条件变量

var origin = "http://127.0.0.1:6666/"
var url = "ws://127.0.0.1:6666/echo"

//错误处理函数
func checkErr(err error, extra string) bool {
   if err != nil {
      formatStr := " Err : %s\n"
      if extra != "" {
         formatStr = extra + formatStr
      }

      fmt.Fprintf(os.Stderr, formatStr, err.Error())
      return true
   }

   return false
}

//连接处理函数
func clientConnHandler(conn *websocket.Conn) {
   gLocker.Lock()
   defer gLocker.Unlock()
   defer conn.Close()
   request := make([]byte, 128)
   for {
      readLen, err := conn.Read(request)
      if checkErr(err, "Read") {
         gCondition.Signal()
         break
      }

      //socket被关闭了
      if readLen == 0 {
         fmt.Println("Server connection close!")

         //条件变量同步通知
         gCondition.Signal()
         break
      } else {
         //输出接收到的信息
         fmt.Println(string(request[:readLen]))

         ////发送
         //conn.Write([]byte("Hello !"))
      }

      request = make([]byte, 128)

   }
}

func main() {
   conn, err := websocket.Dial(url, "", origin)
   if checkErr(err, "Dial") {
      return
   }

   gLocker.Lock()
   gCondition = sync.NewCond(&gLocker)
   _, err = conn.Write([]byte("Hello !"))
   go clientConnHandler(conn)

   //主线程阻塞,等待Singal结束
   for {
      //条件变量同步等待
      gCondition.Wait()
      break
   }
   gLocker.Unlock()
   fmt.Println("Client finish.")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值