arkdro avatar arkdro committed bb46533

both port and server work

Comments (0)

Files changed (1)

erlang/src/c_server.erl

 %%%-----------------------------------------------------------------
 -module(c_server).
 -behaviour(gen_server).
--export([start/0, start_link/0, start_link/1, stop/1]).
+
+-export([
+         ping/0
+        ]).
+
+-export([start_link/0, stop/0]).
 -export([init/1, handle_call/3, handle_cast/2, handle_info/2]).
 -export([terminate/2, code_change/3]).
--define(T, 1000).
 
-%-------------------------------------------------------------------
-start() ->
-    start_link().
+-record(state, {status, port, portcmd, from}).
 
-%-------------------------------------------------------------------
-start_link() ->
-    start_link(none).
+-define(SERVER, ?MODULE).
 
-%-------------------------------------------------------------------
-start_link(Conf) ->
-    gen_server:start_link(?MODULE, Conf, []).
+%%==================================================================
+%% API
+%%==================================================================
+ping() ->
+    gen_server:call(?SERVER, ping).
 
 %-------------------------------------------------------------------
-stop(Pid) ->
-    gen_server:call(Pid, stop).
+start_link() ->
+    gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
 
 %-------------------------------------------------------------------
-init(C) ->
-    {ok, C, ?T}.
+stop() ->
+    gen_server:call(?SERVER, stop).
+
+%%==================================================================
+%% gen_server callbacks
+%%==================================================================
+init(_) ->
+    {ok, PortCommand} = application:get_env(port_command),
+    Port = open_port({spawn, PortCommand}, [{packet, 4}, binary, exit_status]),
+    port_command(Port, term_to_binary(ping)),
+    {ok, #state{status = init, port = Port, portcmd = PortCommand }}.
 
 %-------------------------------------------------------------------
+handle_call(ping, From, #state{status=running, port=Port} = State) ->
+    port_command(Port, term_to_binary(ping)),
+    {noreply, State#state{from=From}};
 handle_call(stop, _From, St) ->
     {stop, normal, ok, St};
 handle_call(status, _From, St) ->
-    {reply, St, St, ?T};
+    {reply, St, St};
 handle_call(_N, _From, St) ->
-    {reply, {error, unknown_request}, St, ?T}.
+    error_logger:info_report({handle_call, unknown, _N}),
+    {reply, {error, unknown_request}, St}.
 
 %-------------------------------------------------------------------
 handle_cast(stop, St) ->
     {stop, normal, St};
-handle_cast(_, St) ->
-    {noreply, St, ?T}.
+handle_cast(_I, St) ->
+    error_logger:info_report({handle_cast, unknown, _I}),
+    {noreply, St}.
 
 %-------------------------------------------------------------------
 terminate(_, _State) ->
     ok.
 
 %-------------------------------------------------------------------
-handle_info(_, State) ->
-    {noreply, State, ?T}.
+handle_info({Port, {data, <<131,100,0,4,"pong">>}},
+            #state{status=init, port = Port} = State) ->
+    {noreply, State#state{status=running}};
+handle_info({Port, {data, <<131,100,0,4,"pong">>}},
+            #state{from=From, port = Port} = State) ->
+    gen_server:reply(From, pong),
+    {noreply, State#state{from=undefined}};
+handle_info({Port, {data, Data}}, #state{port = Port} = State) ->
+    Term = binary_to_term(Data),
+    error_logger:info_report({handle_info, data, Term}),
+    {noreply, State};
+handle_info(_I, State) ->
+    error_logger:info_report({handle_info, unknown, _I}),
+    {noreply, State}.
 
 %-------------------------------------------------------------------
 code_change(_Old_vsn, State, _Extra) ->
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.