2016-09-22 84 views
0

我很难理解参考进去的工作原理。我想写一个非常简单的内存发布 - 订阅机制。下面的代码:参考进去 - 属性不变

package sockets 

import (
    "fmt" 

    "github.com/gorilla/websocket" 
) 

type hubSingleton struct { 
    Clients map[string][]*websocket.Conn 
} 

var instance *hubSingleton 

func Hub() *hubSingleton { 

    if instance == nil { 
     fmt.Println("New instance created") 
     instance = &hubSingleton{} 
    } 
    instance.Clients = make(map[string][]*websocket.Conn, 6) 
    return instance 
} 

func (hub *hubSingleton) Subscribe(channel string, socket *websocket.Conn) error { 
    if _, ok := hub.Clients[channel]; !ok { 
     hub.Clients[channel] = make([]*websocket.Conn, 0) 
    } 
    hub.Clients[channel] = append(hub.Clients[channel], socket) 

    fmt.Println("Subscribe: ", hub.Clients) 
    return nil 
} 

func (hub *hubSingleton) Publish(channel string, message interface{}) { 
    fmt.Println("Publish: ", hub.Clients) 

    if _, ok := hub.Clients[channel]; !ok { 
     return 
    } 
    for i := 0; i < len(hub.Clients[channel]); i++ { 
     conn := hub.Clients[channel][i] 
     conn.WriteJSON(Message{status: "ok", content: message}) 
    } 
} 

的问题是,它似乎每次我打电话集线器()发布()或集线器()订阅()创建一个新的hubSingleton.Client。好吧,我不知道会发生什么,但这里是正在运行的程序的输出:

Publish: map[] 
Subscribe: map[chan:[0xc820170000]] 
Publish: map[] 
Subscribe: map[chan:[0xc82008ac80]] 
Publish: map[] 
Publish: map[] 
Publish: map[] 
Subscribe: map[chan:[0xc820170140]] 
Publish: map[] 

订阅者添加到地图disapear每次我打电话集线器()。 我可以做些什么,使地图上的更改保留在通话之间?

+0

发布你如何调用这段代码的代码。 – eduncan911

回答

2

Hub函数在每次调用时创建一个新的客户端映射。功能更改为:

func Hub() *hubSingleton { 
    if instance == nil { 
    fmt.Println("New instance created") 
    instance = &hubSingleton{} 
    instance.Clients = make(map[string][]*websocket.Conn, 6) 
    } 
    return instance 
} 

如果到Hub第一个电话是从一个请求处理程序,然后有上instance数据争。使用锁来操纵比赛:

var (
    instance *hubSingleton 
    mu sync.Mutex 
) 

func Hub() *hubSingleton { 
    mu.Lock() 
    defer mu.Unlock() 
    if instance == nil { 
    fmt.Println("New instance created") 
    instance = &hubSingleton{} 
    instance.Clients = make(map[string][]*websocket.Conn, 6) 
    } 
    return instance 
} 

一个更简单的方法是使用前一次初始化实例:

var instance *hubSingleton 

func newHub() *hubSingleton { 
    return &hubSingleton{Clients: make(map[string][]*websocket.Conn, 6)} 
} 

func main() { 
    instance = newHub() 
    ... 
} 

如果PublishSubscribe被处理程序同时调用,然后有数据争上Clients in Publish and Subscribe