ไลบรารีไคลเอนต์ที่ให้บริการ WAMP บน Java 8 (Netty) และ Android รวมถึง WebSocket (ปลอดภัย) สำหรับ Android
Autobahn|Java เป็นโปรเจ็กต์ย่อยของโปรเจ็กต์ Autobahn และจัดเตรียมการใช้งานไคลเอ็นต์โอเพ่นซอร์ส
ทำงานบน Android และ Netty/Java8/JVM
เลเยอร์ WebSocket ใช้ API ผู้ใช้แบบเรียกกลับ และเขียนขึ้นสำหรับ Android โดยเฉพาะ เช่นมันไม่ได้รันสิ่งเครือข่ายใด ๆ บนเธรดหลัก (UI)
เลเยอร์ WAMP ใช้ Java 8 CompletableFuture สำหรับการดำเนินการของ WAMP (การโทร การลงทะเบียน เผยแพร่ และสมัครสมาชิก) และ รูปแบบ Observer สำหรับเซสชัน WAMP กิจกรรมวงจรการสมัครสมาชิก และการลงทะเบียน
ไลบรารีนี้ได้รับอนุญาตจาก MIT ซึ่งดูแลโดยโครงการ Crossbar.io ทดสอบโดยใช้ AutobahnTestsuite และเผยแพร่เป็น JAR ไปยัง Maven และเป็นอิมเมจ Docker toolchain ไปยัง Dockerhub
คว้าผ่าน Maven:
< dependency >
< groupId >io.crossbar.autobahn</ groupId >
< artifactId >autobahn-android</ artifactId >
< version >21.7.1</ version >
</ dependency >
เกรด:
dependencies {
implementation ' io.crossbar.autobahn:autobahn-android:21.7.1 '
}
สำหรับระบบที่ไม่ใช่ Android ให้ใช้ artifactID autobahn-java
หรือเพียงดาวน์โหลด JAR ล่าสุด
ไคลเอนต์สาธิตนั้นใช้งานง่าย คุณเพียงแค่ต้องติดตั้ง make
และ docker
เพื่อเริ่มใช้งาน
$ make crossbar # Starts crossbar in a docker container
$ make python # Starts a python based WAMP components that provides calls for the Java demo client
และในที่สุด
$ make java # Starts the java (Netty) based demo client that performs WAMP actions
โค้ดใน demo-gallery มีตัวอย่างบางส่วนเกี่ยวกับวิธีใช้ไลบรารี autobahn และยังมีวิธีการใช้งานที่สะดวกอีกด้วย ด้านล่างนี้คือชุดตัวอย่างโค้ดพื้นฐานที่แสดงการทำงานของ WAMP ทั้ง 4 รายการ
public void demonstrateSubscribe ( Session session , SessionDetails details ) {
// Subscribe to topic to receive its events.
CompletableFuture < Subscription > subFuture = session . subscribe ( "com.myapp.hello" ,
this :: onEvent );
subFuture . whenComplete (( subscription , throwable ) -> {
if ( throwable == null ) {
// We have successfully subscribed.
System . out . println ( "Subscribed to topic " + subscription . topic );
} else {
// Something went bad.
throwable . printStackTrace ();
}
});
}
private void onEvent ( List < Object > args , Map < String , Object > kwargs , EventDetails details ) {
System . out . println ( String . format ( "Got event: %s" , args . get ( 0 )));
}
เนื่องจากเราเข้าถึงเฉพาะ args
ใน onEvent() เราจึงสามารถทำให้มันง่ายขึ้นได้ เช่น:
private void onEvent ( List < Object > args ) {
System . out . println ( String . format ( "Got event: %s" , args . get ( 0 )));
}
public void demonstratePublish ( Session session , SessionDetails details ) {
// Publish to a topic that takes a single arguments
List < Object > args = Arrays . asList ( "Hello World!" , 900 , "UNIQUE" );
CompletableFuture < Publication > pubFuture = session . publish ( "com.myapp.hello" , args );
pubFuture . thenAccept ( publication -> System . out . println ( "Published successfully" ));
// Shows we can separate out exception handling
pubFuture . exceptionally ( throwable -> {
throwable . printStackTrace ();
return null ;
});
}
การโทรที่ง่ายกว่าจะมีลักษณะดังนี้:
public void demonstratePublish ( Session session , SessionDetails details ) {
CompletableFuture < Publication > pubFuture = session . publish ( "com.myapp.hello" , "Hi!" );
...
}
public void demonstrateRegister ( Session session , SessionDetails details ) {
// Register a procedure.
CompletableFuture < Registration > regFuture = session . register ( "com.myapp.add2" , this :: add2 );
regFuture . thenAccept ( registration ->
System . out . println ( "Successfully registered procedure: " + registration . procedure ));
}
private CompletableFuture < InvocationResult > add2 (
List < Object > args , Map < String , Object > kwargs , InvocationDetails details ) {
int res = ( int ) args . get ( 0 ) + ( int ) args . get ( 1 );
List < Object > arr = new ArrayList <>();
arr . add ( res );
return CompletableFuture . completedFuture ( new InvocationResult ( arr ));
}
add2
ที่แม่นยำมากอาจมีลักษณะดังนี้:
private List < Object > add2 ( List < Integer > args , InvocationDetails details ) {
int res = args . get ( 0 ) + args . get ( 1 );
return Arrays . asList ( res , details . session . getID (), "Java" );
}
public void demonstrateCall ( Session session , SessionDetails details ) {
// Call a remote procedure.
CompletableFuture < CallResult > callFuture = session . call ( "com.myapp.add2" , 10 , 20 );
callFuture . thenAccept ( callResult ->
System . out . println ( String . format ( "Call result: %s" , callResult . results . get ( 0 ))));
}
ขั้นตอนการเรียกพร้อมพารามิเตอร์ชนิดข้อมูลตัวแปร
public void demonstrateCall ( Session session , SessionDetails details ) {
// Call a remote procedure.
byte [] var1 = new byte [ 20 ];
String var2 = "A sample text" ;
int var3 = 99 ;
List < Object > args = new ArrayList <>();
args . add ( var1 );
args . add ( var2 );
args . add ( var3 );
CompletableFuture < CallResult > callFuture = session . call ( "com.myapp.myproc" , args );
callFuture . thenAccept ( callResult ->
System . out . println ( String . format ( "Call result: %s" , callResult . results . get ( 0 ))));
}
public void main () {
// Create a session object
Session session = new Session ();
// Add all onJoin listeners
session . addOnJoinListener ( this :: demonstrateSubscribe );
session . addOnJoinListener ( this :: demonstratePublish );
session . addOnJoinListener ( this :: demonstrateCall );
session . addOnJoinListener ( this :: demonstrateRegister );
// finally, provide everything to a Client and connect
Client client = new Client ( session , url , realm );
CompletableFuture < ExitInfo > exitInfoCompletableFuture = client . connect ();
}
การรับรองความถูกต้องนั้นง่ายดาย เราเพียงแค่ต้องสร้างออบเจ็กต์ของตัวตรวจสอบความถูกต้องที่ต้องการและส่งต่อไปยังไคลเอนต์
public void main () {
...
IAuthenticator authenticator = new TicketAuth ( authid , ticket );
Client client = new Client ( session , url , realm , authenticator );
CompletableFuture < ExitInfo > exitInfoCompletableFuture = client . connect ();
}
public void main () {
...
IAuthenticator authenticator = new ChallengeResponseAuth ( authid , secret );
Client client = new Client ( session , url , realm , authenticator );
CompletableFuture < ExitInfo > exitInfoCompletableFuture = client . connect ();
}
public void main () {
...
IAuthenticator authenticator = new CryptosignAuth ( authid , privkey , pubkey );
Client client = new Client ( session , url , realm , authenticator );
CompletableFuture < ExitInfo > exitInfoCompletableFuture = client . connect ();
}
คุณยังสามารถระบุรายชื่อผู้ตรวจสอบสิทธิ์ได้
public void main () {
...
List < IAuthenticator > authenticators = new ArrayList <>();
authenticators . add ( new TicketAuth ( authid , ticket ));
authenticators . add ( new CryptosignAuth ( authid , privkey , pubkey ));
Client client = new Client ( session , url , realm , authenticators );
CompletableFuture < ExitInfo > exitInfoCompletableFuture = client . connect ();
}
Autobahn ยังรองรับ POJO ด้วย
ต่อไปนี้เป็นวิธีเรียกขั้นตอนระยะไกลที่ส่งคืนรายการ Person POJO
// Call a remote procedure that returns a Person with id 1
CompletableFuture < Person > callFuture = mSession . call ( "com.example.get_person" , 1 );
callFuture . whenCompleteAsync (( person , throwable ) -> {
if ( throwable != null ) {
// handle error
} else {
// success!
// do something with person
}
}, mExecutor );
// call a remote procedure that returns a List<Person>
CompletableFuture < List < Person >> callFuture = mSession . call (
// remote procedure to call
"com.example.get_persons_by_department" ,
// positional call arguments
new ArrayList < Object >() { List . of ( "department-7" )},
// call return type
new TypeReference < List < Person >>() {}
);
callFuture . whenCompleteAsync (( persons , throwable ) -> {
if ( throwable != null ) {
// handle error
} else {
// success!
for ( Person person : persons ) {
// do something with person
}
}
}, mExecutor );
ลงทะเบียนขั้นตอนที่ส่งคืนบุคคลด้วย
private Person get_person () {
return new Person ( "john" , "doe" , "hr" );
}
private void main () {
CompletableFuture < Registration > regFuture = session . register (
"io.crossbar.example.get_person" , this :: get_person );
regFuture . whenComplete (( registration , throwable ) -> {
System . out . println ( String . format (
"Registered procedure %s" , registration . procedure ));
});
}
ตัวอย่างเสียงสะท้อน
WebSocketConnection connection = new WebSocketConnection ();
connection . connect ( "wss://echo.websocket.org" , new WebSocketConnectionHandler () {
@ Override
public void onConnect ( ConnectionResponse response ) {
System . out . println ( "Connected to server" );
}
@ Override
public void onOpen () {
connection . sendMessage ( "Echo with Autobahn" );
}
@ Override
public void onClose ( int code , String reason ) {
System . out . println ( "Connection closed" );
}
@ Override
public void onMessage ( String payload ) {
System . out . println ( "Received message: " + payload );
connection . sendMessage ( payload );
}
});
การสร้างออโต้บาห์นนั้นค่อนข้างเรียบง่าย
สำหรับ Android เราแนะนำให้ใช้ Android Studio เพียงนำเข้าโปรเจ็กต์ใน Android Studio มันจะบอกคุณว่ามีการขึ้นต่อกันที่หายไปหรือไม่ ให้ทำการติดตั้ง จากนั้นสร้างโปรเจ็กต์จาก Build > Rebuild Project
แล้วคุณจะมี aar artifact ใน autobahn/build/outputs/aar/
ในการสร้างบิลด์สำหรับระบบที่ไม่ใช่ Android ตรวจสอบให้แน่ใจว่าคุณมีนักเทียบท่าและติดตั้งแล้วเพียงใช้คำสั่ง run below บนไดเร็กทอรีรากของโครงการ
make build_autobahn
และที่จะส่งออกไฟล์ jar ใน autobahn/build/libs/
ติดต่อโดยการเข้าร่วมฟอรั่มของเรา
เวอร์ชัน 1 ของไลบรารีนี้ยังอยู่ใน repo ที่นี่ แต่ไม่ได้รับการบำรุงรักษาอีกต่อไป
เวอร์ชัน 1 รองรับเฉพาะ WebSocket ที่ไม่ปลอดภัยบน Android และรองรับเฉพาะ WAMP v1
ปัญหาทั้งสองนี้ได้รับการแก้ไขแล้วใน Autobahn|Java เวอร์ชัน (ปัจจุบัน)