-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautocomplete_clt.erl
87 lines (79 loc) · 3.32 KB
/
autocomplete_clt.erl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
-module(autocomplete_clt).
-export([initClient/3, start/3]).
%% ServerName: autocomplete server host
%% Port: autocomplete server listing port
%% Pid: calling process id
%% return: same as spawn_link
initClient(ServerName, Port, Pid) ->
spawn_link(fun() -> start(ServerName, Port, Pid) end).
%% ServerName: autocomplete server host
%% Port: autocomplete server listing port
%% Pid: calling process id
%% usage: spawn(start) or spawn_link(start)
start(ServerName, Port, Pid) ->
%% connect to server
case gen_tcp:connect(ServerName, Port, [binary, {packet, 0}]) of
{ok, Socket} ->
loop(ServerName, Port, Socket, Pid, []);
Other ->
io:format("failed to connect to host=~p at port:~p\n", [ServerName, Port]),
Pid ! {connection_failed, Other}
end.
loop(ServerName, Port, Socket, Pid, SoFar) ->
receive
{add, Key, Value, RequestId} ->
io:format("get add request, key=~p, value=~p\n", [Key, Value]),
add(Key, Value, RequestId, Socket),
loop(ServerName, Port, Socket, Pid, SoFar);
{remove, Key, RequestId} ->
io:format("get remove request key=~p\n", [Key]),
remove(Key, RequestId, Socket),
loop(ServerName, Port, Socket, Pid, SoFar);
{search, Key, RequestId} ->
io:format("get search request key=~p\n", [Key]),
search(Key, RequestId, Socket),
loop(ServerName, Port, Socket, Pid, SoFar);
{tcp, Socket, Bin} ->
%io:format("socket received length:~p\n", [size(Bin)]),
case processResponse(Pid, lists:append([SoFar, binary_to_list(Bin)])) of
{more_read, Buffer} ->
loop(ServerName, Port, Socket, Pid, Buffer);
Other ->
{error, Other}
end;
{tcp_closed, _} ->
io:format("connection to server closed, reopen it \n"),
start(ServerName, Port, Pid);
Other ->
{error, Other}
end.
add(Key, Value, RequestId, Socket) ->
% io:format("in add of key:~p\n", [Key]),
P = "{\"method\":\"add\", \"data\":[{\"key\":\"" ++ Key ++ "\",\"value\":\"",
Payload = string:concat(P, Value) ++ "\"}]}",
Len = string:len(Payload),
H = "Content-Length:" ++ integer_to_list(Len) ++ "\r\n" ++ "Request-Id:" ++ RequestId ++ "\r\n\r\n" ++ Payload,
gen_tcp:send(Socket, H).
remove(Key, RequestId, Socket) ->
io:format("in remove of key:~p\n", [Key]),
Payload = "{\"method\":\"remove\", \"data\":[{\"key\":\"" ++ Key ++ "\"}]}",
Len = string:len(Payload),
H = "Content-Length:" ++ integer_to_list(Len) ++ "\r\n" ++ "Request-Id:" ++ RequestId ++ "\r\n\r\n" ++ Payload,
gen_tcp:send(Socket, H).
search(Key, RequestId, Socket) ->
io:format("in search of key:~p\n", [Key]),
Payload = "{\"method\":\"search\", \"data\":[{\"key\":\"" ++ Key ++ "\"}]}",
Len = string:len(Payload),
H = "Content-Length:" ++ integer_to_list(Len) ++ "\r\n" ++ "Request-Id:" ++ RequestId ++ "\r\n\r\n" ++ Payload,
gen_tcp:send(Socket, H).
processResponse(Pid, Resp) ->
case message:parse(Resp) of
{ok, RequestId, Payload, Remaining} ->
%io:format("send response back to pid:~p, resp:~p\n", [Pid, Payload]),
Pid ! {search, RequestId, Payload},
processResponse(Pid, Remaining);
{more_read, Buffer} ->
{more_read, Buffer};
Other ->
Other
end.