Skip to content

Commit

Permalink
- added some comments
Browse files Browse the repository at this point in the history
- added warning message why a connection could not be established.
  • Loading branch information
niclasmeier committed Dec 6, 2012
1 parent f560967 commit d8be07d
Showing 1 changed file with 36 additions and 32 deletions.
68 changes: 36 additions & 32 deletions src/herolabs/apns/push.clj
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@
`(reify org.jboss.netty.channel.ChannelFutureListener `(reify org.jboss.netty.channel.ChannelFutureListener
(operationComplete [this# ^ChannelFuture ~future] ~@body))))) (operationComplete [this# ^ChannelFuture ~future] ~@body)))))


(defn- handler [bootstrap ssl-handler-factory client-handle exception-handler] (defn- handler
"Function to create a ChannelUpstreamHandler" "Function to create a ChannelUpstreamHandler"
[bootstrap ssl-handler-factory client-handle exception-handler]
(proxy [org.jboss.netty.channel.SimpleChannelUpstreamHandler] [] (proxy [org.jboss.netty.channel.SimpleChannelUpstreamHandler] []
(channelConnected [^ChannelHandlerContext ctx ^ChannelStateEvent event] (channelConnected [^ChannelHandlerContext ctx ^ChannelStateEvent event]
(trace "channelConnected") (trace "channelConnected")
Expand Down Expand Up @@ -90,17 +91,12 @@
(.addLast "encoder" (encoder id-gen)) (.addLast "encoder" (encoder id-gen))
(.addLast "decoder" (decoder)) (.addLast "decoder" (decoder))
(.addLast "timeout" (WriteTimeoutHandler. timer (int (if time-out time-out 300)))) (.addLast "timeout" (WriteTimeoutHandler. timer (int (if time-out time-out 300))))
(.addLast "protocoll-handler" protocoll-handler) (.addLast "protocoll-handler" protocoll-handler))))))
))
)
)
)



(defn- default-exception-handler [cause] (info cause "An exception occured while sending push notification to the server.")) (defn- default-exception-handler [cause] (info cause "An exception occured while sending push notification to the server."))


(defn- connect [^InetSocketAddress address ^SSLContext ssl-context time-out boss-executor worker-executor exception-handler] (defn- connect [^InetSocketAddress address ^SSLContext ssl-context time-out boss-executor worker-executor exception-handler]
"creates a netty Channel to connect to the server." "Creates a Netty Channel to connect to the server."
(let [engine-factory (ssl-engine-factory ssl-context :use-client-mode true) (let [engine-factory (ssl-engine-factory ssl-context :use-client-mode true)
bootstrap (-> (NioClientSocketChannelFactory. bootstrap (-> (NioClientSocketChannelFactory.
boss-executor worker-executor) (ClientBootstrap.)) boss-executor worker-executor) (ClientBootstrap.))
Expand All @@ -119,54 +115,62 @@
(do (do
(swap! client-handle (fn [_] channel)) (swap! client-handle (fn [_] channel))
client-handle) client-handle)
nil))) (let [cause (when future (.getCause future))]
(warn cause "Unable to establish connection to" address "due to:" (if cause (.getMessage cause) "An unexpected cause."))
nil))))






(defprotocol Connection (defprotocol Connection
(is-connected? [this] "Determines is a connection is connected") (is-connected? [this] "Determines is a connection is connected")
(write-message [this message] "Writes a message") (write-message [this message] "Writes a message")
(disconnect [this] "Disconnects a connection from the server") (disconnect [this] "Disconnects a connection from the server"))
)


(defprotocol Result (defprotocol Result
(success? [this] "Determines if the send operation was a success.") (success? [this] "Determines if the send operation was a success.")
(done? [this] "Checks if the operation already competed.") (done? [this] "Checks if the operation already competed."))
)

(defn success?
(defn success? [^ChannelFuture future] (when future (-> future (.awaitUninterruptibly) (.isSuccess)))) "Checks of a future finished successful. Also waits uninterruptibly until the future finished to determine the result."

[^ChannelFuture future] (when future (-> future (.awaitUninterruptibly) (.isSuccess))))
(defn create-connection [^InetSocketAddress address ^SSLContext ssl-context & {:keys [time-out boss-executor worker-executor exception-handler]
:or {time-out 300 (defn create-connection
boss-executor (default-thread-pool) "Creates a connection the the Apple push notification service."
worker-executor (default-thread-pool) [^InetSocketAddress address
exception-handler default-exception-handler}}] ^SSLContext ssl-context
"Creates a connection" & {:keys [time-out boss-executor worker-executor exception-handler]
:or {time-out 300
boss-executor (default-thread-pool)
worker-executor (default-thread-pool)
exception-handler default-exception-handler}}]
(let [client-handle (connect address ssl-context time-out boss-executor worker-executor exception-handler)] (let [client-handle (connect address ssl-context time-out boss-executor worker-executor exception-handler)]
(when client-handle (when client-handle
(reify Connection (reify Connection
(is-connected? [_] (when-let [channel @client-handle] (.isConnected channel))) (is-connected? [_] (when-let [channel @client-handle] (.isConnected channel)))
(disconnect [_] (when-let [channel @client-handle] (.close channel))) (disconnect [_] (when-let [channel @client-handle] (.close channel)))
(write-message [_ message] (when-let [channel @client-handle] (.write channel message))))))) (write-message [_ message] (when-let [channel @client-handle] (.write channel message)))))))


(defn send-message [^herolabs.apns.push.Connection connection ^String device-token message & {:keys [completed-listener]}] (defn send-message
"Sends a message in the standard message format to the Apple push service" "Sends a message in the standard message format to the Apple push service"
[^herolabs.apns.push.Connection connection ^String device-token message & {:keys [completed-listener]}]
(when (and connection device-token message) (when (and connection device-token message)
(loop [[listener & rest] (if (sequential? completed-listener) completed-listener [completed-listener]) (loop [[listener & rest] (if (sequential? completed-listener) completed-listener [completed-listener])
future (.write-message connection (with-meta message {:device-token device-token}))] future (.write-message connection (with-meta message {:device-token device-token}))]
(if listener (recur rest (doto future (.addListener listener))) future)))) (if listener (recur rest (doto future (.addListener listener))) future))))


(defn send-enhanced-message [^herolabs.apns.push.Connection connection ^String device-token message] (defn send-enhanced-message
"Sends a message in the enhanced message format to the Apple push service" "Sends a message in the enhanced message format to the Apple push service"
[^herolabs.apns.push.Connection connection ^String device-token message]
(when (and connection device-token message) (when (and connection device-token message)
(let [msg (with-meta message {:device-token device-token :format :enhanced})] (let [msg (with-meta message {:device-token device-token :format :enhanced})]
(.write-message connection msg) (.write-message connection msg))))
)))


(defn dev-address [] (defn dev-address
(InetSocketAddress. "gateway.sandbox.push.apple.com" 2195) "The Apple sandbox address for the push service."
) []
(InetSocketAddress. "gateway.sandbox.push.apple.com" 2195))


(defn prod-address [] (defn prod-address
(InetSocketAddress. "gateway.push.apple.com" 2195) "The productive Apple internet address for the push service."
) []
(InetSocketAddress. "gateway.push.apple.com" 2195))

0 comments on commit d8be07d

Please sign in to comment.