use new webapi to fetch mqttid to replace relayid

And drop relay once we have it. Makes perfecting RelayService backoff
less an issue.
This commit is contained in:
Eric House 2022-02-12 13:27:24 -08:00
parent 4bfcf2afb4
commit 2175600190
10 changed files with 126 additions and 15 deletions

View file

@ -2195,6 +2195,9 @@ public class BoardDelegate extends DelegateBase
return result;
}
@Override
public long getRowID() { return m_rowid; }
} // class BoardUtilCtxt
private void doResume( boolean isStart )

View file

@ -234,8 +234,8 @@ public class NetUtils {
return makeHttpsConn( context, url, proc );
}
protected static HttpsURLConnection makeHttpsMQTTConn( Context context,
String proc )
public static HttpsURLConnection makeHttpsMQTTConn( Context context,
String proc )
{
String url = XWPrefs.getDefaultMQTTUrl( context );
return makeHttpsConn( context, url, proc );
@ -275,8 +275,8 @@ public class NetUtils {
return runConn( conn, param.toString(), false );
}
protected static String runConn( HttpsURLConnection conn, JSONObject param,
boolean directJson )
public static String runConn( HttpsURLConnection conn, JSONObject param,
boolean directJson )
{
return runConn( conn, param.toString(), directJson );
}

View file

@ -96,6 +96,7 @@ public class JNIThread extends Thread implements AutoCloseable {
CMD_NETSTATS,
CMD_PASS_PASSWD,
CMD_SET_BLANK,
CMD_SETMQTTID,
CMD_PAUSE,
CMD_UNPAUSE,
// CMD_DRAW_CONNS_STATUS,
@ -715,6 +716,11 @@ public class JNIThread extends Thread implements AutoCloseable {
((Integer)args[3]).intValue() );
break;
case CMD_SETMQTTID:
draw = false;
XwJNI.comms_addMQTTDevID( m_jniGamePtr, (Integer)args[0], (String)args[1] );
break;
case CMD_TIMER_FIRED:
draw = XwJNI.timerFired( m_jniGamePtr,
((Integer)args[0]).intValue(),

View file

@ -60,6 +60,7 @@ public interface UtilCtxt {
void requestTime();
void remSelected();
void getMQTTIDsFor(String[] relayID);
void timerSelected( boolean inDuplicateMode, boolean canPause );
void informWordsBlocked( int nWords, String words, String dict );
String getInviteeName( int index );

View file

@ -1,7 +1,7 @@
/* -*- compile-command: "find-and-gradle.sh inXw4dDeb"; -*- */
/*
* Copyright 2009 - 2012 by Eric House (xwords@eehouse.org). All
* rights reserved.
* Copyright 2009 - 2022 by Eric House (xwords@eehouse.org). All rights
* reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
@ -22,9 +22,20 @@ package org.eehouse.android.xw4.jni;
import android.content.Context;
import javax.net.ssl.HttpsURLConnection;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
import java.util.Iterator;
import org.eehouse.android.xw4.Assert;
import org.eehouse.android.xw4.Log;
import org.eehouse.android.xw4.NetUtils;
import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnTypeSet;
import org.eehouse.android.xw4.jni.JNIThread.JNICmd;
public class UtilCtxtImpl implements UtilCtxt {
private static final String TAG = UtilCtxtImpl.class.getSimpleName();
@ -96,6 +107,45 @@ public class UtilCtxtImpl implements UtilCtxt {
subclassOverride( "remSelected" );
}
public long getRowID() { return 0; } // to be overridden
@Override
public void getMQTTIDsFor( final String[] relayIDs )
{
final long rowid = getRowID();
if ( 0 == rowid ) {
Log.d( TAG, "getMQTTIDsFor() no rowid available so dropping" );
} else {
new Thread( new Runnable() {
@Override
public void run() {
JSONObject params = new JSONObject();
JSONArray array = new JSONArray();
try ( JNIThread thread = JNIThread.getRetained( rowid ) ) {
params.put( "rids", array );
for ( String rid : relayIDs ) {
array.put( rid );
}
HttpsURLConnection conn = NetUtils
.makeHttpsMQTTConn( m_context, "mids4rids" );
String resStr = NetUtils.runConn( conn, params, true );
Log.d( TAG, "mids4rids => %s", resStr );
JSONObject obj = new JSONObject( resStr );
for ( Iterator<String> keys = obj.keys(); keys.hasNext(); ) {
String key = keys.next();
int hid = Integer.parseInt(key);
thread.handle( JNICmd.CMD_SETMQTTID, hid, obj.getString(key) );
}
} catch ( Exception ex ) {
Log.ex( TAG, ex );
}
}
} ).start();
}
}
@Override
public void timerSelected( boolean inDuplicateMode, boolean canPause )
{

View file

@ -504,6 +504,8 @@ public class XwJNI {
public static native boolean comms_isConnected( GamePtr gamePtr );
public static native String comms_formatRelayID( GamePtr gamePtr, int indx );
public static native String comms_getStats( GamePtr gamePtr );
public static native void comms_addMQTTDevID( GamePtr gamePtr, int channelNo,
String devID );
// Used/defined (in C) for DEBUG only
public static native void comms_setAddrDisabled( GamePtr gamePtr, CommsConnType typ,

View file

@ -625,6 +625,18 @@ and_util_remSelected( XW_UtilCtxt* uc, XWEnv xwe )
UTIL_CBK_TAIL();
}
static void
and_util_getMQTTIDsFor( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nRelayIDs,
const XP_UCHAR* relayIDs[] )
{
UTIL_CBK_HEADER("getMQTTIDsFor", "([Ljava/lang/String;)V" );
jobjectArray jrids = makeStringArray( env, nRelayIDs, relayIDs );
(*env)->CallVoidMethod( env, util->jutil, mid, jrids );
deleteLocalRef( env, jrids );
UTIL_CBK_TAIL();
}
static void
and_util_timerSelected( XW_UtilCtxt* uc, XWEnv xwe, XP_Bool inDuplicateMode, XP_Bool canPause )
{
@ -1018,6 +1030,7 @@ makeUtil( MPFORMAL JNIEnv* env,
SET_PROC(showChat);
#endif
SET_PROC(remSelected);
SET_PROC(getMQTTIDsFor);
SET_PROC(timerSelected);
SET_PROC(formatPauseHistory);

View file

@ -2597,6 +2597,22 @@ Java_org_eehouse_android_xw4_jni_XwJNI_comms_1getStats
return result;
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1addMQTTDevID
( JNIEnv* env, jclass C, GamePtrType gamePtr, jint channel, jstring jdevid )
{
XWJNI_START_GLOBALS();
if ( NULL != state->game.comms ) {
const char* str = (*env)->GetStringUTFChars( env, jdevid, NULL );
MQTTDevID devID;
if ( strToMQTTCDevID( str, &devID ) ) {
comms_addMQTTDevID( state->game.comms, channel, &devID );
}
(*env)->ReleaseStringUTFChars( env, jdevid, str );
}
XWJNI_END();
}
JNIEXPORT void JNICALL
Java_org_eehouse_android_xw4_jni_XwJNI_comms_1dropHostAddr
( JNIEnv* env, jclass C, GamePtrType gamePtr, jobject jConnTyp )

View file

@ -225,6 +225,9 @@ static XP_U16 makeFlags( const CommsCtxt* comms, XP_U16 headerLen, MsgID msgID )
static XP_Bool sendNoConn( CommsCtxt* comms, XWEnv xwe,
const MsgQueueElem* elem, XWHostID destID );
static XP_Bool formatRelayID( const CommsCtxt* comms, XWHostID hostID,
XP_UCHAR* buf, XP_U16* lenp );
#ifdef XWFEATURE_RELAY
static XP_Bool relayConnect( CommsCtxt* comms, XWEnv xwe );
static void relayDisconnect( CommsCtxt* comms, XWEnv xwe );
@ -672,21 +675,31 @@ addrFromStream( CommsAddrRec* addrP, XWStreamCtxt* stream )
/* Return TRUE if there are no addresses left that include relay */
static XP_Bool
removeRelayIf( CommsCtxt* comms )
removeRelayIf( CommsCtxt* comms, XWEnv xwe )
{
XP_Bool allRemoved = XP_TRUE;
XP_UCHAR bufs[MAX_NUM_PLAYERS+1][64];
const XP_UCHAR* ptrs[MAX_NUM_PLAYERS+1];
int nIds = 0;
for ( AddressRecord* rec = comms->recs; !!rec; rec = rec->next ) {
CommsAddrRec* addr = &rec->addr;
if ( addr_hasType( addr, COMMS_CONN_RELAY ) ) {
if ( addr_hasType( addr, COMMS_CONN_MQTT )
&& 0 != addr->u.mqtt.devID ) {
addr_rmType( addr, COMMS_CONN_RELAY );
XP_LOGFF( "we DID remove RELAY" );
} else {
XP_U16 len = VSIZE(bufs[nIds]);
if ( formatRelayID( comms, rec->rr.hostID, bufs[nIds], &len ) ) {
ptrs[nIds] = &bufs[nIds][0];
++nIds;
}
allRemoved = XP_FALSE;
}
}
}
if ( 0 < nIds ) {
util_getMQTTIDsFor( comms->util, xwe, nIds, ptrs );
}
LOG_RETURNF( "%s", boolToStr(allRemoved) );
return allRemoved;
}
@ -818,9 +831,7 @@ comms_makeFromStream( MPFORMAL XWEnv xwe, XWStreamCtxt* stream,
notifyQueueChanged( comms, xwe );
if ( addr_hasType( &comms->addr, COMMS_CONN_RELAY )
&& addr_hasType( &comms->addr, COMMS_CONN_MQTT )
&& 0 != &comms->addr.u.mqtt.devID
&& removeRelayIf( comms ) ) {
&& removeRelayIf( comms, xwe ) ) {
addr_rmType( &comms->addr, COMMS_CONN_RELAY );
}
@ -1105,15 +1116,14 @@ comms_addMQTTDevID( CommsCtxt* comms, XP_PlayerAddr channelNo,
XP_USE( channelNo );
XP_USE( devID );
#else
XP_LOGFF( "(devID: " MQTTDevID_FMT ")", *devID );
XP_LOGFF( "(channelNo: %d, devID: " MQTTDevID_FMT ")", channelNo, *devID );
XP_Bool found = XP_FALSE;
for ( AddressRecord* rec = comms->recs; !!rec && !found; rec = rec->next ) {
found = rec->channelNo == channelNo;
found = (rec->channelNo & ~CHANNEL_MASK) == (channelNo & ~CHANNEL_MASK);
if ( found ) {
if ( addr_hasType( &rec->addr, COMMS_CONN_MQTT ) ) {
XP_ASSERT( *devID == rec->addr.u.mqtt.devID );
}
CommsAddrRec addr = {0};
addr_setType( &addr, COMMS_CONN_MQTT );
addr.u.mqtt.devID = *devID;

View file

@ -152,6 +152,13 @@ typedef struct UtilVtable {
void (*m_util_remSelected)(XW_UtilCtxt* uc, XWEnv xwe);
/* Solving a time-limited problem of games that know how to connect via
relay but not MQTT. Once this method succeeds and the platform
implementation calls comms_addMQTTDevID() we never need it again for
that game. */
void (*m_util_getMQTTIDsFor)( XW_UtilCtxt* uc, XWEnv xwe, XP_U16 nRelayIDs,
const XP_UCHAR* relayIDs[] );
void (*m_util_timerSelected)(XW_UtilCtxt* uc, XWEnv xwe, XP_Bool inDuplicateMode,
XP_Bool canPause);
@ -288,9 +295,12 @@ struct XW_UtilCtxt {
#define util_notifyIllegalWords( uc,e, w, p, b ) \
(uc)->vtable->m_util_notifyIllegalWords((uc), (e),(w),(p),(b))
#define util_remSelected( uc,e ) \
#define util_remSelected( uc,e ) \
(uc)->vtable->m_util_remSelected((uc), (e))
#define util_getMQTTIDsFor( uc, e, cnt, rids ) \
(uc)->vtable->m_util_getMQTTIDsFor((uc), (e), (cnt), (rids))
#define util_timerSelected( uc,e, dm, cp ) \
(uc)->vtable->m_util_timerSelected((uc), (e), (dm), (cp))