/* * Copyright (C) 2014 struktur AG * http://www.strukturag.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is baeed on ideas from the chat example of gorilla/websocket. * Copyright 2013 Gary Burd. All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or * other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ package main type hub struct { grabbers map[string]*grabber connections map[*connection]bool broadcast chan *interfacedata register chan *connection unregister chan *connection } var h = hub{ broadcast: make(chan *interfacedata), register: make(chan *connection), unregister: make(chan *connection), connections: make(map[*connection]bool), grabbers: make(map[string]*grabber), } func (h *hub) run() { var eg *grabber var ok bool for { select { case c := <-h.register: h.connections[c] = true if eg, ok = h.grabbers[c.iface]; !ok { eg = newGrabber(c.iface) h.grabbers[c.iface] = eg } eg.start() case c := <-h.unregister: delete(h.connections, c) close(c.send) if eg, ok = h.grabbers[c.iface]; ok { eg.stop() } case d := <-h.broadcast: for c := range h.connections { if c.iface == d.iface { if m, err := d.encode(); err == nil { select { case c.send <- m: default: close(c.send) delete(h.connections, c) } } } } } } }