handle "Invalid JSON RPC response" error by restarting RPC server
This commit is contained in:
parent
f74944ac2d
commit
6c1f24b211
|
@ -14,5 +14,5 @@ android {
|
|||
|
||||
dependencies {
|
||||
compile 'com.facebook.react:react-native:+'
|
||||
compile(group: 'status-im', name: 'status-go', version: 'jail-isconnected', ext: 'aar')
|
||||
compile(group: 'status-im', name: 'status-go', version: 'restart-rpc', ext: 'aar')
|
||||
}
|
||||
|
|
|
@ -32,6 +32,18 @@ public class StatusConnector extends ServiceConnector {
|
|||
}
|
||||
}
|
||||
|
||||
public void startRPC() {
|
||||
if (checkBound()) {
|
||||
sendMessage(null, StatusMessages.MSG_START_RPC, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void stopRPC() {
|
||||
if (checkBound()) {
|
||||
sendMessage(null, StatusMessages.MSG_STOP_RPC, null);
|
||||
}
|
||||
}
|
||||
|
||||
public void login(String callbackIdentifier, String address, String password) {
|
||||
|
||||
if (checkBound()) {
|
||||
|
|
|
@ -59,4 +59,14 @@ public class StatusMessages {
|
|||
*/
|
||||
public static final int MSG_DISCARD_TRANSACTION = 11;
|
||||
|
||||
/**
|
||||
* Start RPC server
|
||||
*/
|
||||
static final int MSG_START_RPC = 12;
|
||||
|
||||
/**
|
||||
* Stop RPC server
|
||||
*/
|
||||
static final int MSG_STOP_RPC = 13;
|
||||
|
||||
}
|
||||
|
|
|
@ -144,6 +144,28 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
|||
status.startNode(callbackIdentifier);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void startNodeRPCServer() {
|
||||
Log.d(TAG, "startNodeRPCServer");
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
status.startRPC();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void stopNodeRPCServer() {
|
||||
Log.d(TAG, "stopNodeRPCServer");
|
||||
final Activity activity = getCurrentActivity();
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
status.stopRPC();
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void login(String address, String password, Callback callback) {
|
||||
Log.d(TAG, "login");
|
||||
|
|
|
@ -143,6 +143,14 @@ public class StatusService extends Service {
|
|||
callJail(message);
|
||||
break;
|
||||
|
||||
case StatusMessages.MSG_START_RPC:
|
||||
startRPC();
|
||||
break;
|
||||
|
||||
case StatusMessages.MSG_STOP_RPC:
|
||||
stopRPC();
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -188,6 +196,14 @@ public class StatusService extends Service {
|
|||
createAndSendReply(message, StatusMessages.MSG_STOP_NODE, null);
|
||||
}
|
||||
|
||||
private void startRPC() {
|
||||
Statusgo.StartNodeRPCServer();
|
||||
}
|
||||
|
||||
private void stopRPC() {
|
||||
Statusgo.StopNodeRPCServer();
|
||||
}
|
||||
|
||||
private void createAccount(Message message) {
|
||||
|
||||
Bundle data = message.getData();
|
||||
|
|
|
@ -59,6 +59,68 @@ RCT_EXPORT_METHOD(callJail:(NSString *)chatId
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
const int STATE_ACTIVE = 0;
|
||||
const int STATE_LOCKED_WITH_ACTIVE_APP = 1;
|
||||
const int STATE_BACKGROUND = 2;
|
||||
const int STATE_LOCKED_WITH_INACTIVE_APP = 3;
|
||||
int wozniakConstant = STATE_ACTIVE;
|
||||
|
||||
|
||||
static void displayStatusChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
|
||||
{
|
||||
// the "com.apple.springboard.lockcomplete" notification will always come after the "com.apple.springboard.lockstate" notification
|
||||
CFStringRef nameCFString = (CFStringRef)name;
|
||||
NSString *lockState = (__bridge NSString*)nameCFString;
|
||||
NSLog(@"Darwin notification NAME = %@",name);
|
||||
|
||||
NSString* sm = [NSString stringWithFormat:@"%i", wozniakConstant];
|
||||
NSString *s1 = [NSString stringWithFormat:@"%@ %@", @"LOCK MAGIC", sm];
|
||||
NSLog(s1);
|
||||
if([lockState isEqualToString:@"com.apple.springboard.lockcomplete"])
|
||||
{
|
||||
NSLog(@"DEVICE LOCKED");
|
||||
// User locks phone when application is active
|
||||
if(wozniakConstant == STATE_ACTIVE){
|
||||
wozniakConstant = STATE_LOCKED_WITH_ACTIVE_APP;
|
||||
StopNodeRPCServer();
|
||||
}
|
||||
|
||||
// Here lockcomplete event comes when app is unlocked
|
||||
// because it couldn't come when locking happened
|
||||
// as application was not active (it could not handle callback)
|
||||
if (wozniakConstant == STATE_LOCKED_WITH_INACTIVE_APP) {
|
||||
wozniakConstant = STATE_ACTIVE;
|
||||
StopNodeRPCServer();
|
||||
StartNodeRPCServer();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
NSLog(@"LOCK STATUS CHANGED");
|
||||
NSString *s = [NSString stringWithFormat:@"%@ %@", @"LOCK", lockState];
|
||||
NSLog(s);
|
||||
|
||||
// if lockstate happens before lockcomplete it means
|
||||
// that phone was locked when application was not active
|
||||
if(wozniakConstant == STATE_ACTIVE){
|
||||
wozniakConstant = STATE_LOCKED_WITH_INACTIVE_APP;
|
||||
}
|
||||
|
||||
if(wozniakConstant == STATE_BACKGROUND){
|
||||
wozniakConstant = STATE_ACTIVE;
|
||||
StartNodeRPCServer();
|
||||
}
|
||||
|
||||
// one more lockstate event comes along with lockcomplete
|
||||
// when phone is locked with active application
|
||||
if(wozniakConstant == STATE_LOCKED_WITH_ACTIVE_APP){
|
||||
wozniakConstant = STATE_BACKGROUND;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - startNode
|
||||
//////////////////////////////////////////////////////////////////// startNode
|
||||
|
@ -83,23 +145,57 @@ RCT_EXPORT_METHOD(startNode:(RCTResponseSenderBlock)onResultCallback) {
|
|||
}else
|
||||
NSLog(@"folderName: %@", folderName);
|
||||
|
||||
NSString *peer1 = @"enode://5f23bf4913dd005ce945648cb12d3ef970069818d8563a3fe054e5e1dc3898b9cb83e0af1f51b2dce75eaffc76e93f996caf538e21c5b64db5fa324958d59630@95.85.40.211:30303";
|
||||
NSString *peer2 = @"enode://b9de2532421f15ac55da9d9a7cddc0dc08b0d646d631fd7ab2a170bd2163fb86b095dd8bde66b857592812f7cd9539f2919b6c64bc1a784a1d1c6ec8137681ed@188.166.229.119:30303";
|
||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void) {
|
||||
StartNode((char *) [folderName.path UTF8String]);
|
||||
});
|
||||
NSString *peer1 = @"enode://5f23bf4913dd005ce945648cb12d3ef970069818d8563a3fe054e5e1dc3898b9cb83e0af1f51b2dce75eaffc76e93f996caf538e21c5b64db5fa324958d59630@95.85.40.211:30303";
|
||||
NSString *peer2 = @"enode://b9de2532421f15ac55da9d9a7cddc0dc08b0d646d631fd7ab2a170bd2163fb86b095dd8bde66b857592812f7cd9539f2919b6c64bc1a784a1d1c6ec8137681ed@188.166.229.119:30303";
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)),
|
||||
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
|
||||
^(void) {
|
||||
AddPeer((char *) [peer1 UTF8String]);
|
||||
AddPeer((char *) [peer2 UTF8String]);
|
||||
});
|
||||
});
|
||||
onResultCallback(@[[NSNull null]]);
|
||||
//Screen lock notifications
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
|
||||
NULL, // observer
|
||||
displayStatusChanged, // callback
|
||||
CFSTR("com.apple.springboard.lockcomplete"), // event name
|
||||
NULL, // object
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
|
||||
CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), //center
|
||||
NULL, // observer
|
||||
displayStatusChanged, // callback
|
||||
CFSTR("com.apple.springboard.lockstate"), // event name
|
||||
NULL, // object
|
||||
CFNotificationSuspensionBehaviorDeliverImmediately);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - StartNodeRPCServer method
|
||||
//////////////////////////////////////////////////////////////////// createAccount
|
||||
RCT_EXPORT_METHOD(startNodeRPCServer) {
|
||||
#if DEBUG
|
||||
NSLog(@"StartNodeRPCServer() method called");
|
||||
#endif
|
||||
StartNodeRPCServer();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#pragma mark - StopNodeRPCServer method
|
||||
//////////////////////////////////////////////////////////////////// createAccount
|
||||
RCT_EXPORT_METHOD(stopNodeRPCServer) {
|
||||
#if DEBUG
|
||||
NSLog(@"StopNodeRPCServer() method called");
|
||||
#endif
|
||||
StopNodeRPCServer();
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(stopNode:(RCTResponseSenderBlock)callback) {
|
||||
#if DEBUG
|
||||
NSLog(@"stopNode() method called");
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
<artifactItem>
|
||||
<groupId>status-im</groupId>
|
||||
<artifactId>status-go-ios-simulator</artifactId>
|
||||
<version>jail-isconnected</version>
|
||||
<version>restart-rpc2</version>
|
||||
<type>zip</type>
|
||||
<overWrite>true</overWrite>
|
||||
<outputDirectory>./</outputDirectory>
|
||||
|
|
|
@ -122,4 +122,4 @@
|
|||
;; Clipboard
|
||||
|
||||
(defn copy-to-clipboard [text]
|
||||
(.setString (.-Clipboard react-native) text))
|
||||
(.setString (.-Clipboard react-native) text))
|
||||
|
|
|
@ -62,6 +62,29 @@
|
|||
(when status
|
||||
(call-module #(.startNode status on-result))))
|
||||
|
||||
(defn stop-rpc-server []
|
||||
(when status
|
||||
(call-module #(.stopNodeRPCServer status))))
|
||||
|
||||
(defn start-rpc-server []
|
||||
(when status
|
||||
(call-module #(.startNodeRPCServer status))))
|
||||
|
||||
(defonce restarting-rpc (atom false))
|
||||
|
||||
(defn restart-rpc []
|
||||
(when-not @restarting-rpc
|
||||
(reset! restarting-rpc true)
|
||||
(log/debug :restrt-rpc-on-post-error)
|
||||
|
||||
;; todo maybe it would be better to use something like
|
||||
;; restart-rpc-server on status-go side
|
||||
(stop-rpc-server)
|
||||
(start-rpc-server)
|
||||
|
||||
(go (<! (timeout 3000))
|
||||
(reset! restarting-rpc false))))
|
||||
|
||||
(defonce account-creation? (atom false))
|
||||
|
||||
(defn create-account [password on-result]
|
||||
|
|
|
@ -24,7 +24,8 @@
|
|||
status-im.network.handlers
|
||||
[status-im.utils.types :as t]
|
||||
[status-im.constants :refer [console-chat-id]]
|
||||
[status-im.utils.ethereum-network :as enet]))
|
||||
[status-im.utils.ethereum-network :as enet]
|
||||
[status-im.protocol.core :as protocol]))
|
||||
|
||||
;; -- Common --------------------------------------------------------------
|
||||
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
(.addListener keyboard
|
||||
"keyboardWillHide"
|
||||
#(when-not (= 0 @keyboard-height)
|
||||
(dispatch [:set :keyboard-height 0])))
|
||||
(dispatch [:set :keyboard-height 0])))
|
||||
(.hide splash-screen))
|
||||
:render
|
||||
(fn []
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
::d/delivery-options))
|
||||
|
||||
(def stop-watching-all! f/remove-all-filters!)
|
||||
(def reset-all-pending-messages! d/reset-all-pending-messages!)
|
||||
|
||||
(defn init-whisper!
|
||||
[{:keys [rpc-url identity groups callback
|
||||
|
|
|
@ -12,38 +12,42 @@
|
|||
[status-im.i18n :refer [label]]
|
||||
[status-im.utils.random :as random]
|
||||
[taoensso.timbre :as log :refer-macros [debug]]
|
||||
[status-im.constants :as c]))
|
||||
[status-im.constants :as c]
|
||||
[status-im.components.status :as status]))
|
||||
|
||||
(register-handler :initialize-protocol
|
||||
(fn [db [_ current-account-id]]
|
||||
(let [{:keys [public-key status updates-public-key
|
||||
updates-private-key]}
|
||||
(get-in db [:accounts current-account-id])]
|
||||
(let [groups (chats/get-active-group-chats)
|
||||
w3 (protocol/init-whisper!
|
||||
{:rpc-url c/ethereum-rpc-url
|
||||
:identity public-key
|
||||
:groups groups
|
||||
:callback #(dispatch [:incoming-message %1 %2])
|
||||
:ack-not-received-s-interval 125
|
||||
:default-ttl 120
|
||||
:send-online-s-interval 180
|
||||
:ttl {}
|
||||
:max-attempts-number 3
|
||||
:delivery-loop-ms-interval 500
|
||||
:profile-keypair {:public updates-public-key
|
||||
:private updates-private-key}
|
||||
:hashtags (u/get-hashtags status)
|
||||
:pending-messages (pending-messages/get-all)
|
||||
:contacts (keep (fn [{:keys [whisper-identity
|
||||
public-key
|
||||
private-key]}]
|
||||
(when (and public-key private-key)
|
||||
{:identity whisper-identity
|
||||
:keypair {:public public-key
|
||||
:private private-key}}))
|
||||
(contacts/get-all))})]
|
||||
(assoc db :web3 w3)))))
|
||||
(if public-key
|
||||
(let [groups (chats/get-active-group-chats)
|
||||
w3 (protocol/init-whisper!
|
||||
{:rpc-url c/ethereum-rpc-url
|
||||
:identity public-key
|
||||
:groups groups
|
||||
:callback #(dispatch [:incoming-message %1 %2])
|
||||
:ack-not-received-s-interval 125
|
||||
:default-ttl 120
|
||||
:send-online-s-interval 180
|
||||
:ttl {}
|
||||
:max-attempts-number 3
|
||||
:delivery-loop-ms-interval 500
|
||||
:profile-keypair {:public updates-public-key
|
||||
:private updates-private-key}
|
||||
:hashtags (u/get-hashtags status)
|
||||
:pending-messages (pending-messages/get-all)
|
||||
:contacts (keep (fn [{:keys [whisper-identity
|
||||
public-key
|
||||
private-key]}]
|
||||
(when (and public-key private-key)
|
||||
{:identity whisper-identity
|
||||
:keypair {:public public-key
|
||||
:private private-key}}))
|
||||
(contacts/get-all))
|
||||
:post-error-callback #(dispatch [::post-error %])})]
|
||||
(assoc db :web3 w3))
|
||||
db))))
|
||||
|
||||
(register-handler :update-sync-state
|
||||
(u/side-effect!
|
||||
|
@ -175,7 +179,7 @@
|
|||
(register-handler ::you-removed-from-group
|
||||
(u/side-effect!
|
||||
(fn [{:keys [web3]}
|
||||
[_ {:keys [from]
|
||||
[_ {:keys [from]
|
||||
{:keys [group-id timestamp] :as payload} :payload}]]
|
||||
(when (chats/new-update? timestamp group-id)
|
||||
(let [message
|
||||
|
@ -191,7 +195,7 @@
|
|||
(register-handler :participant-left-group
|
||||
(u/side-effect!
|
||||
(fn [{:keys [current-public-key]}
|
||||
[_ {:keys [from]
|
||||
[_ {:keys [from]
|
||||
{:keys [group-id timestamp] :as payload} :payload}]]
|
||||
(when (and (not= current-public-key from)
|
||||
(chats/is-active? group-id)
|
||||
|
@ -344,3 +348,10 @@
|
|||
(dispatch [:update-contact! contact])
|
||||
(dispatch [:watch-contact contact]))
|
||||
(dispatch [:add-chat from chat])))))))
|
||||
|
||||
(register-handler ::post-error
|
||||
(u/side-effect!
|
||||
(fn [_ [_ error]]
|
||||
(.log js/console error)
|
||||
(when (re-find (re-pattern "Could not connect to the server.") (.-message error))
|
||||
(status/restart-rpc)))))
|
||||
|
|
|
@ -127,9 +127,12 @@
|
|||
:last-attempt (u/timestamp)))))
|
||||
|
||||
(defn delivery-callback
|
||||
[web3 {:keys [id requires-ack? to]}]
|
||||
[web3 post-error-callback {:keys [id requires-ack? to]}]
|
||||
(fn [error _]
|
||||
(when error (log/warn :shh-post-error error))
|
||||
(when error
|
||||
(log/warn :shh-post-error error)
|
||||
(when post-error-callback
|
||||
(post-error-callback error)))
|
||||
(when-not error
|
||||
(debug :delivery-callback)
|
||||
(message-was-sent! web3 id to)
|
||||
|
@ -143,10 +146,12 @@
|
|||
(s/def ::default-ttl ::pos-int)
|
||||
(s/def ::send-online-s-interval ::pos-int)
|
||||
(s/def ::online-message fn?)
|
||||
(s/def ::post-error-callback fn?)
|
||||
|
||||
(s/def ::delivery-options
|
||||
(s/keys :req-un [::delivery-loop-ms-interval ::ack-not-received-s-interval
|
||||
::max-attempts-number ::default-ttl ::send-online-s-interval]
|
||||
::max-attempts-number ::default-ttl ::send-online-s-interval
|
||||
::post-error-callback]
|
||||
:opt-un [::online-message]))
|
||||
|
||||
(defn should-be-retransmitted?
|
||||
|
@ -180,7 +185,7 @@
|
|||
|
||||
(defn run-delivery-loop!
|
||||
[web3 {:keys [delivery-loop-ms-interval default-ttl ttl-config
|
||||
send-online-s-interval online-message]
|
||||
send-online-s-interval online-message post-error-callback]
|
||||
:as options}]
|
||||
{:pre [(valid? ::delivery-options options)]}
|
||||
(debug :run-delivery-loop!)
|
||||
|
@ -201,7 +206,7 @@
|
|||
(when (should-be-retransmitted? options data)
|
||||
(try
|
||||
(let [message' (check-ttl message type ttl-config default-ttl)
|
||||
callback (delivery-callback web3 data)]
|
||||
callback (delivery-callback web3 post-error-callback data)]
|
||||
(t/post-message! web3 message' callback))
|
||||
(catch :default err
|
||||
(log/error :post-message-error err))
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
(defn handle-qr-request
|
||||
[db [_ context data]]
|
||||
(let [handler (get-in db [:qr-codes context])]
|
||||
(when-let [handler (get-in db [:qr-codes context])]
|
||||
(dispatch [handler context data])))
|
||||
|
||||
(defn clear-qr-request [db [_ context]]
|
||||
|
|
Loading…
Reference in New Issue