1:- module(imodule,[
2 imodule/3,
3 iuse_module/3
4 ]). 5
6:- use_module(library(socket)). 7
8:- meta_predicate imodule(+,:,+). 9
10imodule(Port,M,Options) :-
11 ssl_context(server,SSL,Options),
12 tcp_socket(Socket),
13 tcp_bind(Socket,Port),
14 tcp_listen(Socket,5),
15 tcp_open_socket(Socket,AcceptFd),
16
17 18 19 thread_create(dispatch(AcceptFd, M, SSL), _,
20 [ detached(true)
21 ]).
22
23dispatch(AcceptFd, M, SSL) :-
24 tcp_accept(AcceptFd, Socket, Peer),
25
26 27 thread_create(process_client(Socket, Peer, M, SSL), _,
28 [ detached(true)
29 ]),
30 dispatch(AcceptFd, M, SSL).
31
32process_client(Socket, _, M, SSL):-
33 setup_call_cleanup(
34 tcp_open_socket(Socket, StreamPair),
35 customer_service(SSL,StreamPair,M),
36 close(StreamPair)
37 ).
38
39customer_service(SSL,StreamPair,M):-
40 stream_pair(StreamPair,PlainRead,PlainWrite),
41 setup_call_cleanup(
42 ssl_negotiate(SSL,PlainRead,PlainWrite,SSLRead,SSLWrite),
43 run_server(SSLRead,SSLWrite,M),
44 ( close(SSLRead),
45 close(SSLWrite)
46 )
47 ).
48
49run_server(R,W,Module:M):-
50 read(R,K),
51 ( K = list
52 -> portray_clause(W,M)
53 ; K = run
54 -> read(R,F),
55 functor(F,A,N),
56 memberchk(A/N,M),
57 call(Module:F),
58 portray_clause(W,F)
59 ; portray_clause(W,error)
60 ),
61 flush_output(W).
62
63:- meta_predicate iuse_module(:,+,+). 64
65iuse_module(Module:URI,Port,Options):-
66 ssl_context(client,SSL,[host(client)|Options]),
67 setup_call_cleanup(
68 tcp_connect(URI:Port, SP, []),
69 get_predicates(SSL,SP,L),
70 close(SP)
71 ),
72 create_predicates(L,Module,URI:Port,SSL).
73
74get_predicates(SSL,SP,L):-
75 stream_pair(SP,PlainRead,PlainWrite),
76 setup_call_cleanup(
77 ssl_negotiate(SSL,PlainRead,PlainWrite,SSLRead,SSLWrite),
78 ( portray_clause(SSLWrite,list),
79 flush_output(SSLWrite),
80 read(SSLRead,L)
81 ),
82 ( close(SSLWrite),
83 close(SSLRead)
84 )
85 ).
86
87create_predicates([],_,_,_).
88create_predicates([A/N|H],Module,URI,SSL):-
89 functor(F,A,N),
90 Module:abolish(A/N),
91 Module:dynamic(A/N),
92 Module:asserta(F:-
93 setup_call_cleanup(
94 tcp_connect(URI, SP, []),
95 ( stream_pair(SP,PlainRead,PlainWrite),
96 setup_call_cleanup(
97 ssl_negotiate(SSL,PlainRead,PlainWrite,SSLRead,SSLWrite),
98 ( portray_clause(SSLWrite,run),
99 portray_clause(SSLWrite,F),
100 flush_output(SSLWrite),
101 read(SSLRead,F)
102 ),
103 ( close(SSLRead),
104 close(SSLWrite)
105 )
106 )
107 ),
108 close(SP)
109 )),
110 Module:compile_predicates([A/N]),
111 create_predicates(H,Module,URI,SSL)