link

所属分类:collect
开发工具:Clojure
文件大小:0KB
下载次数:0
上传日期:2021-08-19 12:11:56
上 传 者sh-1993
说明:  用于非阻塞网络编程的clojure框架,
(A clojure framework for nonblocking network programming,)

文件列表:
.travis.yml (18, 2021-08-19)
dev-resources/ (0, 2021-08-19)
dev-resources/log4j.properties (194, 2021-08-19)
examples/ (0, 2021-08-19)
examples/link/ (0, 2021-08-19)
examples/link/examples/ (0, 2021-08-19)
examples/link/examples/echo.clj (1021, 2021-08-19)
examples/link/examples/http/ (0, 2021-08-19)
examples/link/examples/http/async.clj (201, 2021-08-19)
examples/link/examples/http/h2.clj (524, 2021-08-19)
examples/link/examples/http/h2c.clj (244, 2021-08-19)
examples/link/examples/http/simple.clj (162, 2021-08-19)
project.clj (1607, 2021-08-19)
src/ (0, 2021-08-19)
src/link/ (0, 2021-08-19)
src/link/codec.clj (9945, 2021-08-19)
src/link/core.clj (5558, 2021-08-19)
src/link/http.clj (9157, 2021-08-19)
src/link/http/ (0, 2021-08-19)
src/link/http/common.clj (1512, 2021-08-19)
src/link/http/http2.clj (4995, 2021-08-19)
src/link/mock.clj (817, 2021-08-19)
src/link/ssl.clj (1772, 2021-08-19)
src/link/tcp.clj (7363, 2021-08-19)
src/link/threads.clj (513, 2021-08-19)
src/link/util.clj (390, 2021-08-19)
src/link/websocket.clj (8026, 2021-08-19)
test/ (0, 2021-08-19)
test/link/ (0, 2021-08-19)
test/link/codec_test.clj (2315, 2021-08-19)
test/link/core_test.clj (905, 2021-08-19)
test/link/mock_test.clj (694, 2021-08-19)
test/link/threads_test.clj (324, 2021-08-19)
test/link/websocket_test.clj (829, 2021-08-19)

# link link is the event-driven network library used by [slacker](https://github.com/sunng87/slacker). It's a thin wrapper of Netty. [![Build Status](https://travis-ci.org/sunng87/link.png?branch=master)](https://travis-ci.org/sunng87/link) ## Usage ### Leiningen ![https://clojars.org/link](https://clojars.org/link/latest-version.svg) Currently, link only works on the JVM implementation of Clojure. We might support nodejs in future. ### API #### Codec In most cases, we use a declarative DSL to define a custom tcp protocol codec: `link.codec`. With the codec, you can read/write Clojure data structure in your handler and don't have to read the message byte by byte, and worry about TCP framing. ```clojure user> (require '[link.codec :refer :all]) ;; create a custom codec: [version target-id string-message] user> (def custom-codec (frame (byte) (int32) (string :encoding :utf8 :prefix (uint16)))) ;; create an empty buffer user> (def buf (unpooled-buffer)) ;; encode clojure data structure on to given buffer, by using codec. ;; note that you don't have to call `encode*` and `decode*` by ;; youself, link does it for you. user> (encode* custom-codec [1 348 "hello world"] buf) #object[io.netty.buffer.UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf 0x4eb69819 "UnpooledByteBufAllocator$InstrumentedUnpooledUnsafeHeapByteBuf(ridx: 0, widx: 18, cap: 256)"] user> (decode* custom-codec buf) [1 348 "hello world"] ``` For a more complex codec, check slacker's codec definition. #### handler You need to create a custom handler to process you network message. Link has provided you a dsl that is easier to understand. And also hide complexity of Netty's default handler API. ```clojure (require '[link.core :refer :all]) (def echo-handler (create-handler (on-message [ch msg] (send! ch msg)))) ``` There are 5 events you can process in a link handler: * `(on-active [ch])` when channel is open, bound or connected * `(on-inacitve [ch])` when channel is no longer open, bound or connected * `(on-message [ch msg])` when a packet is read in * `(on-error [ch e])` when exception occurs on I/O thread * `(on-event [ch evt])` when netty user defined event triggered And for the channel `ch`, you can call following functions as defined by `LinkMessageChannel` protocol. * `(send! [ch msg])` write a msg into channel * `(channel-addr [ch])` get the local socket address of the channel * `(remote-addr [ch])` get the remote socket address of the channel * `(close! [ch])` request to close the channel * `(valid? [ch])` test if channel is still open and active #### the TCP server link only supports non-blocking server and client. To start a server, you can provide a few argument to customize it: ```clojure (require '[link.tcp :refer :all]) (require '[link.threads :refer :all]) ;; Just to demo the usage here, there is no need to run a echo-handler ;; in a thread pool. (def handler-spec {:handler echo-handler :executor (new-executor 10)}) ;; you can also provide a few handlers by passing a vector of them (tcp-server 8081 [handler-spec] :options {:so-reuseaddr true} ;; netty, ip, tcp and socket options :host ;; if to bind, default "0.0.0.0" ) ``` From link 0.7, ssl handler and codecs are all normal handlers. You will need to put them at correct position of handlers. To see a full list of TCP options, you can find it on [Netty doc](http://netty.io/4.1/api/io/netty/channel/ChannelOption.html). Change the option name to lowercase and replace the underscore with dash, as in Clojure way. Prefixing a `clild-` to specify option for child channels: `:child-tcp-nodelay`. You can stop a server by ``` clojure ;; calling stop-server with the value returned by tcp-server (stop-server *1) ``` #### the TCP client To create a TCP client, you need to create a connection factory for it. Note that, clients created from the same factory will share the same selector and event loop. Managing it carefully if you have a large number of connections. ```clojure (def client-factory (tcp-client-factory handlers :options ...)) ``` Create a client ```clojure (def client (tcp-client client-factory "localhost" 8081)) ``` The value returned by `tcp-client` is a `LinkMessageChannel` object so you can call any functions of the protocol on it. To send some data: ```clojure (send! client [1 345 "hello world"]) ``` To close a client, call `close!` on the channel. To close a client factory, call `stop-clients` would work. #### HTTP Server link also comes with an HTTP server. Since link is a clojure library, it accepts a ring function, so you can use any HTTP framework on link http server, without pain. ```clojure (require '[link.http :refer :all]) (http-server 8080 ring-app-fn :executor ... ;; the thread pool to run ring functions on) ``` #### HTTP/2 Server ```clojure (require '[link.http :as h]) (require '[link.ssl :as ssl]) (import '[io.netty.handler.ssl.util SelfSignedCertificate]) (let [ssc (SelfSignedCertificate.) ssl-context (ssl/ssl-context-for-http2 (.certificate ssc) (.privateKey ssc) :jdk)] (h/h2-server 8443 ring-app ssl-context :threads 8)) ``` #### Websocket New in link 0.5. You can start a websocket server with link. Create a websocket handler: ```clojure (require '[link.websocket :refer :all]) (require '[link.tcp :refer :all]) (def ws-echo-handler (create-ws-handler (on-open [ch]) (on-close [ch]) (on-text [ch string] ;; you can use (text), (binary), (ping), (pong) to generate ;; different types of response (send! ch (text string))) (on-binary [ch ^ByteBuf bytes]) (on-ping [ch ^ByteBuf bytes]) (on-pong [ch ^ByteBuf bytes]))) (tcp-server 8082 (conj (websocket-codecs "/chat") ws-echo-handler)) ``` ## License Copyright (C) 2012-2019 Ning Sun and contributors Distributed under the Eclipse Public License, the same as Clojure.

近期下载者

相关文件


收藏者