v / examples / jsonrpc / server.v
213 lines · 184 sloc · 4.07 KB · efc8f7fb3ef7e90a088db64ad2c68dd0698b90d5
Raw
1module main
2
3import net
4import sync
5import net.jsonrpc
6import log
7
8// ---- CRUD domain ----
9struct KvItem {
10 key string
11 value string
12}
13
14struct KvKey {
15 key string
16}
17
18// ---- Handler ----
19struct KvStore {
20mut:
21 mu &sync.RwMutex = sync.new_rwmutex()
22 store map[string]string
23}
24
25fn (mut s KvStore) create(key string, value string) bool {
26 s.mu.@lock()
27 defer { s.mu.unlock() }
28 if key in s.store {
29 return false
30 }
31 s.store[key] = value
32 return true
33}
34
35fn (mut s KvStore) get(key string) ?string {
36 s.mu.@rlock()
37 defer { s.mu.runlock() }
38 if value := s.store[key] {
39 return value
40 }
41 return none
42}
43
44fn (mut s KvStore) update(key string, value string) bool {
45 s.mu.@lock()
46 defer { s.mu.unlock() }
47 if key in s.store {
48 s.store[key] = value
49 return true
50 }
51 return false
52}
53
54fn (mut s KvStore) delete(key string) bool {
55 s.mu.@lock()
56 defer { s.mu.unlock() }
57 if key in s.store {
58 s.store.delete(key)
59 return true
60 }
61 return false
62}
63
64fn (s KvStore) dump() map[string]string {
65 return s.store
66}
67
68@[heap]
69struct KvHandler {
70mut:
71 store KvStore
72}
73
74fn (mut h KvHandler) handle_create(req &jsonrpc.Request, mut wr jsonrpc.ResponseWriter) {
75 p := req.decode_params[KvItem]() or {
76 wr.write_error(jsonrpc.invalid_params)
77 return
78 }
79 if p.key.len == 0 {
80 wr.write_error(jsonrpc.invalid_params)
81 return
82 }
83 log.warn('params=${p}')
84 if !h.store.create(p.key, p.value) {
85 wr.write_error(jsonrpc.ResponseError{ // custom app-level error code
86 code: -32010
87 message: 'Key already exists'
88 data: p.key
89 })
90 return
91 }
92
93 wr.write({
94 'ok': true
95 })
96}
97
98fn (mut h KvHandler) handle_get(req &jsonrpc.Request, mut wr jsonrpc.ResponseWriter) {
99 p := req.decode_params[KvKey]() or {
100 wr.write_error(jsonrpc.invalid_params)
101 return
102 }
103
104 value := h.store.get(p.key) or {
105 wr.write_error(jsonrpc.ResponseError{
106 code: -32004
107 message: 'Not found'
108 data: p.key
109 })
110 return
111 }
112
113 wr.write(KvItem{ key: p.key, value: value })
114}
115
116fn (mut h KvHandler) handle_update(req &jsonrpc.Request, mut wr jsonrpc.ResponseWriter) {
117 p := req.decode_params[KvItem]() or {
118 wr.write_error(jsonrpc.invalid_params)
119 return
120 }
121
122 if !h.store.update(p.key, p.value) {
123 wr.write_error(jsonrpc.ResponseError{
124 code: -32004
125 message: 'Not found'
126 data: p.key
127 })
128 return
129 }
130
131 wr.write({
132 'ok': true
133 })
134}
135
136fn (mut h KvHandler) handle_delete(req &jsonrpc.Request, mut wr jsonrpc.ResponseWriter) {
137 p := req.decode_params[KvKey]() or {
138 wr.write_error(jsonrpc.invalid_params)
139 return
140 }
141
142 if !h.store.delete(p.key) {
143 wr.write_error(jsonrpc.ResponseError{
144 code: -32004
145 message: 'Not found'
146 data: p.key
147 })
148 return
149 }
150
151 wr.write({
152 'ok': true
153 })
154}
155
156fn (mut h KvHandler) handle_list(_req &jsonrpc.Request, mut wr jsonrpc.ResponseWriter) {
157 mut items := []KvItem{}
158 for k, v in h.store.dump() {
159 items << KvItem{
160 key: k
161 value: v
162 }
163 }
164 items.sort(a.key < b.key)
165 wr.write(items)
166}
167
168// ---- Per-connection server loop ----
169// The jsonrpc.Server.start() reads from stream and writes to same stream.
170fn handle_conn(mut conn net.TcpConn, h jsonrpc.Handler) {
171 defer { conn.close() or {} }
172
173 mut log_inter := jsonrpc.LoggingInterceptor{}
174 mut inters := jsonrpc.Interceptors{
175 event: [log_inter.on_event]
176 encoded_request: [log_inter.on_encoded_request]
177 request: [log_inter.on_request]
178 response: [log_inter.on_response]
179 encoded_response: [log_inter.on_encoded_response]
180 }
181
182 mut srv := jsonrpc.new_server(jsonrpc.ServerConfig{
183 stream: conn
184 handler: h
185 interceptors: inters
186 })
187
188 jsonrpc.dispatch_event(inters.event, 'start', 'server started')
189 srv.start()
190}
191
192fn main() {
193 mut s := KvStore{}
194 mut h := KvHandler{
195 store: s
196 }
197 mut r := jsonrpc.Router{}
198 r.register('kv.create', h.handle_create)
199 r.register('kv.get', h.handle_get)
200 r.register('kv.update', h.handle_update)
201 r.register('kv.delete', h.handle_delete)
202 r.register('kv.list', h.handle_list)
203
204 addr := '127.0.0.1:42228'
205 mut l := net.listen_tcp(.ip, addr)!
206 println('TCP JSON-RPC server on ${addr} (Content-Length framing)')
207
208 for {
209 mut c := l.accept()!
210 println('Accepted')
211 go handle_conn(mut c, r.handle_jsonrpc)
212 }
213}
214