otp - About a client for pusher written in Erlang -
i want write module need able push message pusher in erlang. found repo https://github.com/bradfordw/pusherl, not maintained anymore, think can adapt make work. followed readme, , ran rebar command. open rebar console command
./rel/pusherl/bin/pusherl console
so server should start. when try call
gen_server:call(pusherl_server, {push, {"channelname", "eventname", "payload"}}).
then throws error:
exception exit: {noproc,{gen_server,call, [pusherl_server, {push, {"channelname","eventname","payload"}}]}} in function gen_server:call/2 (gen_server.erl, line 182)
i'm quite new erlang , otp, , takes me half of day make work not successful. please me solve this. appreciate.
by way, if know other pusher client, please suggest me. lot.
here code gen_server callback:
-module(pusherl_server). -behaviour(gen_server). -define(server, ?module). -define(jp, fun(k,v) -> string:join([k,v],"=") end). -record(state,{app_id, key, secret}). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). start_link() -> gen_server:start_link({local, ?server}, ?module, [], []). init(_) -> {ok, pusherappid} = application:get_env(pusher_app_id), {ok, pusherkey} = application:get_env(pusher_key), {ok, pushersecret} = application:get_env(pusher_secret), {ok, #state{app_id=pusherappid, key=pusherkey, secret=pushersecret}}. handle_call({push, {channelname, eventname, payload}}, _from, state) -> case http_request(channelname, eventname, payload, state) of {ok, _} -> {reply, ok, state}; {error, _} -> {reply, error, state} end; handle_call(_request, _from, state) -> {noreply, ok, state}. handle_cast({push, {channelname, eventname, payload}}, state) -> case http_request(channelname, eventname, payload, state) of {ok, _} -> {noreply, ok, state}; {error, _} -> {noreply, error, state} end; handle_cast(_msg, state) -> {noreply, state}. handle_info(_info, state) -> {noreply, state}. terminate(_reason, _state) -> ok. code_change(_oldvsn, state, _extra) -> {ok, state}. http_request(channelname, eventname, payload, config) when is_list(channelname), is_record(config, state) -> {ok, reqprops} = http_request_props(payload, eventname, channelname, config), httpc:request(post, reqprops, [], []). http_request_props(payload, eventname, channelname, #state{app_id=appid, key=appkey, secret=appsecret}) -> md5string = lists:flatten([io_lib:format("~2.16.0b",[n]) || <<n>> <= crypto:md5(payload)]), tosign = ["post", lists:flatten(["/apps/", appid, "/channels/", channelname, "/events"]), string:join([?jp("auth_key", appkey), ?jp("auth_timestamp", get_time_as_string()), ?jp("auth_version", "1.0"), ?jp("body_md5", md5string), ?jp("name", eventname) ],"&") ], authsignature = signed_params(tosign, appsecret), queryparams = [ ?jp("auth_key", appkey), ?jp("auth_timestamp", get_time_as_string()), ?jp("auth_version","1.0"), ?jp("body_md5", md5string), ?jp("auth_signature", authsignature), ?jp("name", eventname) ], url = http_api_url(appid, channelname, queryparams), {ok, {url, [], "application/x-www-form-urlencoded", payload}}. http_api_url(appid, channelname, queryparams) -> querystring = string:join(queryparams,"&"), lists:flatten(["http://api.pusherapp.com/apps/",appid,"/channels/",channelname,"/events?", querystring]). get_time_as_string() -> {m, s, _} = now(), integer_to_list(((m * 1000000) + s)). signed_params(params, secret) -> lists:flatten([io_lib:format("~2.16.0b",[n]) || <<n:8>> <= sha2:hmac_sha256(secret, string:join(params,"\n"))]).
noproc
means process you're trying call not running. need start with:
pusherl_server:start_link().
note link pusherl_server
process calling process. if you're running in shell, , causes error, error propagate across link pusherl_server
process , kill it, have start again.
to avoid that, can either unlink process after starting it:
{ok, pid} = pusherl_server:start_link(). unlink(pid).
or add start
function module, same start_link
except calls gen_server:start
instead of gen_server:start_link
.
Comments
Post a Comment