ATX learning (c) -atxserver2-android-provider

Server code

Code clone to local, setting up the appropriate environment (how the ride is not presented here, a good ride, ha)
general library first look main.py file, debug mode starts running

Beginning no contact with the tornado.ioloop, a bit biased bottom, headaches, or refuel do it

To understand some of the more in-depth, first under ioloop some knowledge of it, before this prior knowledge to understand the point

A, epoll

ioloop implementation based on epoll, then what is epoll? epoll is the Linux kernel to handle high-volume document describes the
character and made improvements poll. What is it that poll? First, we find out, when the server socket communication, when it accepts (accept) after establishing a connection and communication (connection) to communicate, at a time when we do not know the client connection information there is no finished. At this time there are two options:

  • Here to stay until the end of the send and receive data;
  • At regular intervals to see if there are no data;

    The second approach better than the first, multiple connections can be unified within a certain period of time in turn go over there did not
    have data to read and write, looks can handle multiple connections, this way is to poll / select solution Program. It seems to solve the problem, but in fact, as more and more connected, polling takes
    time will be longer and longer, while the socket server connections are mostly not active, so most of the polling takes
    time It will be useless. To solve this problem, epoll is created, similar to the concept and its poll, but each time the poll, he will only have to pick out the data polling active socket, so when connecting a large number of polling will save a lot time.

As for the operation epoll, in fact, very simple, as long as the four API can fully operate it.

epoll_create

To create a epoll descriptor (that is, create a epoll)

epoll_ctl

The operation epoll Event; available parameters are:

parameter meaning
EPOLL_CTL_ADD Add a new epoll event
EPOLL_CTL_DEL To delete a epoll event
EPOLL_CTL_MOD Change the way an event listener

While listening mode There are seven events, but we only need to be concerned about three of them:

Macro definition meaning
EPOLLIN Buffer full, data is read
EPOLLOUT Buffer empty, writable data
EPOLLERR An error occurred

epoll_wait

Is to make epoll to work, there are arguments timeout, when setting a non-zero positive integer, listens (blocking) timeout seconds; 0 is set to return immediately, you have been listening to -1.

It returns a handle to the list of active files when there is an active data connection when listening (here socket file handle)

close

Close epoll

Now a quick look at epoll, we can come to understand the code ioloop

Two ioloop.py file

ioloop is the key to the tornado, it is his bottom.
ioloop is to I / O multiplexing package that implements a single embodiment, this embodiment is stored in a single in IOLoop._instance
has two main points. Is a configurable mechanism, that is, a cycle epoll

2.1 Creating instance IOLoop

View IOLoop, its superclass is Configurable class, that is to say: IOLoop is disposed directly under a subclass of
class IOLoop (Configurable):
......
necessary here to explain in conjunction with Configurable class:
Configurable in the new method
1 first example of a 'class object execution' configuration the immediate subclass, class method is invoked and returns configurable_default assigned to impl:

2.2 epoll

Starting from the start (), and consequently do not say, on the code

 

 

asyncio.get_event_loop () method, in an inner loop that he does not need to obtain coroutine loop transfer function as a parameter to the coroutine

Note get_event_loop () method only take effect in the same thread, if a new thread, it should be) to obtain a new loop with new_event_loop (, and by set_event_loop (loop) to set it to loop in the thread.
(Temporarily down to here, wandering the topic, embarrassing)
continue
to run main.py file start IOLoop.current (). Run_sync (async_main) is doing

IOLoop function run_sync method of adding call parameters, this is easy to understand.
(Here temporarily absent deep, afraid and went wide, recorded yi have time to continue)

the async (coroutine syntax)

On to the force, continue to use the new stuff, this is python3.5 provide async and await the new syntax for the asyncio
want to know the coroutine can look at this, by way of example to understand better https: // zhuanlan .zhihu.com / p / 25228075
Note: The async keyword defines a coroutine (coroutine), also a coroutine object. Coroutine not directly run, the need to co-drive added to the event loop (loop), call the coroutine at the appropriate time by the latter.
Asynchronous function defined async def async_main ()

Three continue to look at the code it

#Define asynchronous function

the async DEF async_main (): 
        # establish an analysis target ArgumentParser formatter_class: Reset help information output format 
        Parser = argparse.ArgumentParser ( 
            formatter_class = argparse.ArgumentDefaultsHelpFormatter) 
        # add parameters with options for applications - is an optional parameter, default default parameters value 
        parser.add_argument ( 
            ' -s ' , ' --server ' , default = ' localhost: 4000 ' , Help = ' Server address ' ) 
        # Action parameter processing method 
        parser.add_argument ( 
            "--allow-remote", action="store_true", help="allow remote connect device")
        parser.add_argument(
            '-t', '--test', action="store_true", help="run test code")
        # type参数的数据类型
        parser.add_argument(
            '-p', '--port', type=int, default=3500, help='listen port')
        parser.add_argument("--owner", type=str, help="provider owner email")
        parser.add_argument(
            "--owner-file", type=argparse.FileType("r"), help="provider owner email from file")

 

 

3.1 calls parse_args ()

To resolve the object stored ArgumentParser command line parameters: parsing command-line arguments to the corresponding data type and take appropriate action, it returns a Namespace object.

args = parser.parse_args()
 
 

 

3.2 heartbeat_connect waiting for a connection

Here will be run directly

 


What is the reason, it should be easy to see the need to connect localhost: 4000, did not play service, well, run rethinkdb database, and then start atx-server2

 


Well, then run

 

3.3 enter make_app ()

Routing control using tornado.web.Application

3.4 heartbeat_connect去连接设备,这里可以看到过程中基本都是异步方法aysc,运行到_connect这个方法时:

async def _connect(self):
      ws = await websocket.websocket_connect(self._server_ws_url)
      ws.__class__ = SafeWebSocket

      await ws.write_message({
          "command": "handshake",
          "name": self._name,
          "owner": self._owner,
          "secret": self._secret,
          "url": self._provider_url,
          "priority": self._priority,  # the large the importanter
      })
 

发现通过websockt 服务来连接

3.5 hbc.open()

IOLoop.current().spawn_callback(coroutine_visit) #开始调用协程
 

3.6 device_watch()

開始使用adb進行監控 127.0.0.1:5037 这里就不再说name多了
_init_binaries() 这里刚开始获取了设备信息] [设备名] [sdk: 28, abi: arm64-v8a, abis: ['arm64-v8a', 'armeabi-v7a', 'armeabi']
根据设备选择要使用的atx 代理use atx-agent: atx-agent-armv7

3.7 _install_apk()安装whatsInput 和ATX这里只看这两个,另一个属于测试包

这里手机初始化准备好后会向前端页面发送
websocket send: {'udid': '2d869e6', 'platform': 'android', 'colding': False, 'provider': {'atxAgentAddress': '127.0.0.1:20001', 'remoteConnectAddress': 'Ip:20004',

'whatsInputAddress': '127.0.0.1:20003'}, 'properties': {'serial': '设备名', 'brand': 'Xiaomi', 'version': '9', 'model': 'MI 9', 'name': 'MI 9'}, 'command': 'update'}

暂时写到这里吧,明天有时间看下atx-server2的部分代码,觉得结合着看更方便去了解

目前还在学习中,希望会对大家有所帮助,觉得不错,就点赞支持一下。 另外,有什么错误的地方需要大家指正。谢谢!

Guess you like

Origin www.cnblogs.com/dangkai/p/10938494.html