All Projects → clojure-link → link

clojure-link / link

Licence: other
A clojure framework for nonblocking network programming

Programming Languages

clojure
4091 projects

Projects that are alternatives of or similar to link

netty-raknet
A reliable and high performance RakNet library designed with strict Netty patterns.
Stars: ✭ 24 (-61.9%)
Mutual labels:  netty
rpc
自己编写的rpc调用框架,配置简单,使用更简单,如果您感觉有用请点赞,纯个人手写
Stars: ✭ 29 (-53.97%)
Mutual labels:  netty
fire-im
分布式IM服务,参考https://github.com/crossoverJie/cim 实现
Stars: ✭ 17 (-73.02%)
Mutual labels:  netty
CloudSchedule
分布式调度系统,基于zookeeper ,netty,调度内核参考Spring schedule 执行表达式和Spring schedule一样,没有使用Quartz,客户端完全基于注解配置,使用同 Spring schedule一致,最少配置,使用简单
Stars: ✭ 14 (-77.78%)
Mutual labels:  netty
litchi
这是一款分布式的java游戏服务器框架
Stars: ✭ 97 (+53.97%)
Mutual labels:  netty
netty-learning
bio, nio到 netty各种使用案例, 包含基础使用案例,各api使用方法,零拷贝,websocket,群聊,私聊,编码,解码,自定义协议,protobuf等使用案例,rpc服务器,客户端等等学习
Stars: ✭ 49 (-22.22%)
Mutual labels:  netty
resp-server
Netty implementation of REdis Serialization Protocol, and a simple framework to implement command based protocols
Stars: ✭ 40 (-36.51%)
Mutual labels:  netty
SpeedDate
SpeedDate Masterserver: Connecting Players
Stars: ✭ 24 (-61.9%)
Mutual labels:  network-programming
push
基于springboot & netty & kafka 实现的消息推送服务
Stars: ✭ 32 (-49.21%)
Mutual labels:  netty
Java Note
后端研发——笔记
Stars: ✭ 54 (-14.29%)
Mutual labels:  netty
netty-queue
Simple queue: java, json-rest, netty
Stars: ✭ 21 (-66.67%)
Mutual labels:  netty
RPC
RPC is a highly available pluggable architecture for remote calls
Stars: ✭ 31 (-50.79%)
Mutual labels:  netty
Pudding
Pudding 是一款迷你级分布式服务框架
Stars: ✭ 24 (-61.9%)
Mutual labels:  netty
netty-native-demo
Instant Netty startup using GraalVM's Native Image Generation
Stars: ✭ 58 (-7.94%)
Mutual labels:  netty
dns4s
Scala DNS implementation with Akka and Netty extension
Stars: ✭ 55 (-12.7%)
Mutual labels:  netty
piccolo
Netty4长连接网关
Stars: ✭ 19 (-69.84%)
Mutual labels:  netty
packet
📦 Send network packets over a TCP or UDP connection.
Stars: ✭ 68 (+7.94%)
Mutual labels:  network-programming
netty-chat-tutorial
Netty Chat tutorial with Protobuf
Stars: ✭ 23 (-63.49%)
Mutual labels:  netty
spring-boot-protocol
springboot功能扩充-netty动态协议,可以支持各种网络协议的动态切换(单端口支持多个网络协议).支持mmap,sendfile零拷贝,http请求批量聚合
Stars: ✭ 68 (+7.94%)
Mutual labels:  netty
simple-rpc-plus
使用netty和zookeeper技术实现的远程调用框架
Stars: ✭ 16 (-74.6%)
Mutual labels:  netty

link

link is the event-driven network library used by slacker. It's a thin wrapper of Netty.

Build Status

Usage

Leiningen

https://clojars.org/link

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.

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.

(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:

(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. 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

;; 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.

(def client-factory
  (tcp-client-factory handlers
                      :options ...))

Create a client

(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:

(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.

(require '[link.http :refer :all])

(http-server 8080 ring-app-fn
             :executor ... ;; the thread pool to run ring functions on)

HTTP/2 Server

(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:

(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 [email protected] and contributors

Distributed under the Eclipse Public License, the same as Clojure.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].