websocket server base on go language

ranhuan · · 1236 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

之前使用pusher.com提供的商业服务器,但在我的站速度慢,消息传递有丢失情况,所以自行构架

主要实现通知功能:

1. 根据每个page的 session_id来区分连接,数组方式存放,应对当一个session打开了多个page的情形

2.json格式进行通讯,数据中指定要通知的session,该session下的所有page将收到通知,session_id至少做md5处理                                                                    

package main

import (
        "flag"
        "fmt"
        "net/http"
        "code.google.com/p/go.net/websocket")

var port *int = flag.Int("p", 443, "Port to listen.")

//创建全局map,可以为sess_id,value为ws数组(指针)
var conns = make(map[string][]*websocket.Conn)

//type Msg struct {
//        Sender string
//        Receiver string
//        Command string
//        Data map(string)interface{}
//}

// jsonServer echoes back json string sent from client using websocket.JSON.
func server(ws *websocket.Conn) {
        defer ws.Close()

        req := ws.Request()
        req.ParseForm()

        //client := req.FormValue("client")
        sess_id := req.FormValue("sess_id");
        //ver := req.FormValue("ver")

        //其它地方发起一个通知请求,按要求进行处理

        //登记连接
        if client, ok := conns[sess_id]; !ok {
                conns[sess_id] = []*websocket.Conn{ws}
        } else {
                conns[sess_id] = append(client, ws)
        }

        //ws_list, _ := conns[sess_id]
        //ws_list[1] = ws
        //defer delete(conns, sess_id)

        for {
                // Receive receives a text message serialized T as JSON.
                var msg map[string]interface{}
                err := websocket.JSON.Receive(ws, &msg)
                if err != nil {
                        fmt.Println(err)
                        break
                }
                fmt.Printf("recv:%#v\n", msg)
                // Send send a text message serialized T as JSON.
                var receiver string
                for k,v := range msg {
                    if k == "Receiver" {
                        receiver = v.(string)
                    }
                }
                if receiver_ws_list, ok := conns[receiver]; ok {
                        //fmt.Printf("sess client count: %#i\n", len(receiver_ws_list))
                        for _, receiver_ws := range receiver_ws_list {
                                err = websocket.JSON.Send(receiver_ws, msg)
                                if (err != nil) {
                                        fmt.Println("failed to send!")
                                }
                        }
                        fmt.Println("sended!")
                }
                if err != nil {
                        fmt.Println(err)
                        break
                }

                fmt.Printf("send:%#v\n", msg)
        }

        my_ws_list, _ := conns[sess_id]
        for i, my_ws := range my_ws_list {
                if my_ws == ws {
                        conns[sess_id] = append(my_ws_list[:i], my_ws_list[i+1:]...)
                        fmt.Printf("a client removed\n")
                }
        }
        //remove ws form slice
        fmt.Printf("a client closed\n")
}

func main() {
        flag.Parse()
        http.Handle("/", websocket.Handler(server))

        fmt.Printf("http://localhost:%d/\n", *port)

        err := http.ListenAndServe(fmt.Sprintf(":%d", *port), nil)
        if err != nil {
            panic("ListenANdServe: " + err.Error())
        }
}

有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:ranhuan

查看原文:websocket server base on go language

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1236 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传