1// Copyright 2012 Gary Burd 2// 3// Licensed under the Apache License, Version 2.0 (the "License"): you may 4// not use this file except in compliance with the License. You may obtain 5// a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 11// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 12// License for the specific language governing permissions and limitations 13// under the License. 14 15package redis 16 17import ( 18 "errors" 19) 20 21// Subscription represents a subscribe or unsubscribe notification. 22type Subscription struct { 23 24 // Kind is "subscribe", "unsubscribe", "psubscribe" or "punsubscribe" 25 Kind string 26 27 // The channel that was changed. 28 Channel string 29 30 // The current number of subscriptions for connection. 31 Count int 32} 33 34// Message represents a message notification. 35type Message struct { 36 37 // The originating channel. 38 Channel string 39 40 // The message data. 41 Data []byte 42} 43 44// PMessage represents a pmessage notification. 45type PMessage struct { 46 47 // The matched pattern. 48 Pattern string 49 50 // The originating channel. 51 Channel string 52 53 // The message data. 54 Data []byte 55} 56 57// PubSubConn wraps a Conn with convenience methods for subscribers. 58type PubSubConn struct { 59 Conn Conn 60} 61 62// Close closes the connection. 63func (c PubSubConn) Close() error { 64 return c.Conn.Close() 65} 66 67// Subscribe subscribes the connection to the specified channels. 68func (c PubSubConn) Subscribe(channel ...interface{}) error { 69 c.Conn.Send("SUBSCRIBE", channel...) 70 return c.Conn.Flush() 71} 72 73// PSubscribe subscribes the connection to the given patterns. 74func (c PubSubConn) PSubscribe(channel ...interface{}) error { 75 c.Conn.Send("PSUBSCRIBE", channel...) 76 return c.Conn.Flush() 77} 78 79// Unsubscribe unsubscribes the connection from the given channels, or from all 80// of them if none is given. 81func (c PubSubConn) Unsubscribe(channel ...interface{}) error { 82 c.Conn.Send("UNSUBSCRIBE", channel...) 83 return c.Conn.Flush() 84} 85 86// PUnsubscribe unsubscribes the connection from the given patterns, or from all 87// of them if none is given. 88func (c PubSubConn) PUnsubscribe(channel ...interface{}) error { 89 c.Conn.Send("PUNSUBSCRIBE", channel...) 90 return c.Conn.Flush() 91} 92 93// Receive returns a pushed message as a Subscription, Message, PMessage or 94// error. The return value is intended to be used directly in a type switch as 95// illustrated in the PubSubConn example. 96func (c PubSubConn) Receive() interface{} { 97 reply, err := Values(c.Conn.Receive()) 98 if err != nil { 99 return err 100 } 101 102 var kind string 103 reply, err = Scan(reply, &kind) 104 if err != nil { 105 return err 106 } 107 108 switch kind { 109 case "message": 110 var m Message 111 if _, err := Scan(reply, &m.Channel, &m.Data); err != nil { 112 return err 113 } 114 return m 115 case "pmessage": 116 var pm PMessage 117 if _, err := Scan(reply, &pm.Pattern, &pm.Channel, &pm.Data); err != nil { 118 return err 119 } 120 return pm 121 case "subscribe", "psubscribe", "unsubscribe", "punsubscribe": 122 s := Subscription{Kind: kind} 123 if _, err := Scan(reply, &s.Channel, &s.Count); err != nil { 124 return err 125 } 126 return s 127 } 128 return errors.New("redigo: unknown pubsub notification") 129} 130