websocket server base on go language

之前使用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())
        }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值