[英]Websocket: Working with Dart client and Autobahn-python server
I'm new to websocket and trying to use a client written in Dart/flutter to connect to a server written in Python using Autobahn.我是 websocket 的新手,正在尝试使用用 Dart/flutter 编写的客户端连接到使用 Autobahn 用 Python 编写的服务器。
Since Autobahn's server example documentation gives no case about using a ws://
address, I tried to create such a server myself based on its server factory docs , but it failed.由于Autobahn 的服务器示例文档没有给出有关使用
ws://
地址的案例,因此我尝试根据其服务器工厂文档自己创建这样的服务器,但失败了。
server code looks like this服务器代码看起来像这样
# from autobahn.twisted.websocket import WebSocketServerProtocol
from autobahn.asyncio.websocket import WebSocketServerProtocol
class MyServerProtocol(WebSocketServerProtocol):
def onConnect(self, request):
print("Client connecting: {}".format(request.peer))
def onOpen(self):
print("WebSocket connection open.")
def onMessage(self, payload, isBinary):
if isBinary:
print("Binary message received: {} bytes".format(len(payload)))
else:
print("Text message received: {}".format(payload.decode('utf8')))
# echo back message verbatim
self.sendMessage(payload, isBinary)
def onClose(self, wasClean, code, reason):
print("WebSocket connection closed: {}".format(reason))
if __name__ == '__main__':
import asyncio
from autobahn.asyncio.websocket import WebSocketServerFactory
factory = WebSocketServerFactory(url='ws://myhost.com/somepat:9001')
factory.protocol = MyServerProtocol
loop = asyncio.get_event_loop()
coro = loop.create_server(factory, '127.0.0.1', 9001)
server = loop.run_until_complete(coro)
try:
print('starting server ...')
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
server.close()
loop.close()
client code adapted from flutter documentation , only the channel is my own:客户端代码改编自flutter文档,只有通道是我自己的:
import 'package:flutter/foundation.dart';
import 'package:web_socket_channel/io.dart';
import 'package:flutter/material.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final title = 'WebSocket Demo';
return MaterialApp(
title: title,
home: MyHomePage(
title: title,
// channel: IOWebSocketChannel.connect('ws://echo.websocket.org'),
channel: IOWebSocketChannel.connect('ws://myhost.com/somepat:9001'),
),
);
}
}
class MyHomePage extends StatefulWidget {
final String title;
final WebSocketChannel channel;
MyHomePage({Key key, @required this.title, @required this.channel})
: super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
TextEditingController _controller = TextEditingController();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Form(
child: TextFormField(
controller: _controller,
decoration: InputDecoration(labelText: 'Send a message'),
),
),
StreamBuilder(
stream: widget.channel.stream,
builder: (context, snapshot) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 24.0),
child: Text(snapshot.hasData ? '${snapshot.data}' : ''),
);
},
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _sendMessage,
tooltip: 'Send message',
child: Icon(Icons.send),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _sendMessage() {
if (_controller.text.isNotEmpty) {
widget.channel.sink.add(_controller.text);
}
}
@override
void dispose() {
widget.channel.sink.close();
super.dispose();
}
}
Running the above server and client code, I expect to see any input string from the client get echoed back from the server and show on the UI below the text entry on the client smartphone.运行上面的服务器和客户端代码,我希望看到来自客户端的任何输入字符串都从服务器返回并显示在客户端智能手机文本条目下方的 UI 上。
Nothing comes back.什么都没有回来。 The log from client side
来自客户端的日志
Launching lib/main.dart on LIO AN00m in debug mode...
Running Gradle task 'assembleDebug'...
✓ Built build/app/outputs/flutter-apk/app-debug.apk.
Installing build/app/outputs/flutter-apk/app.apk...
Debug service listening on ws://127.0.0.1:54635/rsYDNkqGhYI=/ws
Syncing files to device LIO AN00m...
I/DecorView[](28048): old windowMode:1 new windoMode:1
I/AwareBitmapCacher(28048): init lrucache size: 2097152 pid=28048
D/stylus (28048): init stylus touchlistener.
I/Hwaps (28048): APS: EventAnalyzed: initAPS: version is 11.0.0.4
D/Hwaps (28048): Fpsrequest create,type:EXACTLY_IDENTIFY
D/Hwaps (28048): Fpsrequest create,type:EXACTLY_IDENTIFY
D/Hwaps (28048): Fpsrequest create,type:OPENGL_SETTING
D/Hwaps (28048): FpsController create
D/Hwaps (28048): APS: EventAnalyzed: reInitFpsPara :mBaseFps = 60; mMaxFps = 60
W/Settings(28048): Setting device_provisioned has moved from android.provider.Settings.Secure to android.provider.Settings.Global.
V/HiTouch_HiTouchSensor(28048): User setup is finished.
W/HwApsManager(28048): HwApsManagerService, registerCallback, start !
D/Hwaps (28048): APS: EventAnalyzed: registerCallbackInApsManagerService, mPkgName:com.example.flutter_websocket; result = true
W/InputMethodManager(28048): startInputReason = 4
I/InputMethodManager(28048): showSoftInput
W/InputMethodManager(28048): startInputReason = 3
V/AudioManager(28048): querySoundEffectsEnabled...
I tried a few different address strings, such as我尝试了几个不同的地址字符串,例如
'ws://127.0.0.1:9001'
'ws://localhost:9001'
But none of them work.但它们都不起作用。
It seems that I lack some fundamental knowledge to get started.看来我缺乏一些入门的基础知识。 I come from the ZeroMQ world where all addresses are pretty much tags hiding implementation details, which was friendly to.network programming noobs like me, but also seems to prevent me from understanding the WebSocket protocol.
我来自 ZeroMQ 世界,其中所有地址几乎都是隐藏实现细节的标签,这对像我这样的网络编程新手很友好,但似乎也让我无法理解 WebSocket 协议。
Where am I wrong and how to debug such a case?我错在哪里以及如何调试这种情况? Any pointers are appreciated.
任何指针表示赞赏。
You need to enter the IP address of your pc/server in the python code you can check that out by running ipconfig
, you should enter the same IP on the dart app as well.您需要在 python 代码中输入您的 pc/服务器的 IP 地址,您可以通过运行
ipconfig
检查出来,您也应该在 dart 应用程序上输入相同的 IP。 localhost is a hostname that refers to the current device used to access it, other devices cant access other localhosts but can access their IP address. localhost 是一个主机名,指的是当前用于访问它的设备,其他设备无法访问其他本地主机,但可以访问其 IP 地址。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.