重写_register_hook, 所有的模型加载完成之后会执行这个函数, 在这里执行确保所有模型都是可以访问的状态。
xxxxxxxxxx
1
@api.model_cr
2
def _register_hook(self):
3
""" stuff to do right after the registry is built """
4
global msg_client
5
msg_client = TransitThread(self.env)
6
msg_client.start()
已复制
xxxxxxxxxx
1
# -*- coding: utf-8 -*-
2
3
import socket
4
import threading
5
import select
6
import collections
7
import time
8
from odoo import models, api
9
10
11
class Singleton(object):
12
def __new__(cls, *args, **kwargs):
13
if not hasattr(cls, '_inst'):
14
cls._inst = super(Singleton, cls).__new__(cls)
15
return cls._inst
16
17
18
class TransitClient:
19
write_list = collections.deque()
20
cache_recv_msg = ''
21
running = False
22
read_callback = None
23
24
def __init__(self, server_addr):
25
self.server_addr = server_addr
26
self.msg_socket = None
27
self.cache_recv_msg = ""
28
29
def do_connect(self):
30
try:
31
self.msg_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
32
self.msg_socket.connect(self.server_addr)
33
self.msg_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
34
self.msg_socket.setblocking(0)
35
self.running = True
36
except socket.error as identifier:
37
print(time.ctime(), "connect to", self.server_addr, "error: ", identifier)
38
print("try reconnect...")
39
raise identifier
40
41
def do_close(self):
42
self.msg_socket.close()
43
self.cache_recv_msg = ''
44
45
def set_read_callback(self, callback):
46
self.read_callback = callback
47
48
def write(self, msg):
49
self.write_list.append(msg)
50
51
def do_write(self):
52
try:
53
send_data = bytes(self.format_msg(self.write_list[0]), 'utf-8')
54
self.msg_socket.send(send_data)
55
self.write_list.popleft()
56
return True
57
except socket.error as identifier:
58
print(time.ctime(), "send to", self.server_addr, "error: ", identifier)
59
return False
60
61
def do_read(self):
62
try:
63
data = self.msg_socket.recv(4096)
64
self.cache_recv_msg += data.decode('utf-8')
65
self.parse_data()
66
return True
67
except socket.error as identifier:
68
print(time.ctime(), "recv from", self.server_addr, "error: ", identifier)
69
return False
70
71
@staticmethod
72
def format_msg(msg):
73
return '%d|%s' % (len(msg), msg)
74
75
def parse_data(self):
76
pos = self.cache_recv_msg.find('|')
77
if pos == -1:
78
return
79
size = int(self.cache_recv_msg[: self.cache_recv_msg.find('|')])
80
need_size = size + pos + 1
81
if need_size <= len(self.cache_recv_msg):
82
content = self.cache_recv_msg[pos + 1: size + pos + 1]
83
if self.read_callback:
84
self.read_callback(content)
85
else:
86
print('recved data:', content)
87
self.cache_recv_msg = self.cache_recv_msg[need_size:]
88
if need_size != len(self.cache_recv_msg):
89
self.parse_data()
90
91
def run(self):
92
while True:
93
if self.running:
94
sock_read, sock_write, sock_error = select.select([self.msg_socket], [self.msg_socket], [self.msg_socket])
95
ret = True
96
# self.write('22222')
97
if sock_write and self.write_list:
98
ret = self.do_write()
99
if sock_read:
100
ret = self.do_read()
101
if sock_error or not ret:
102
self.running = False
103
time.sleep(0.01)
104
else:
105
print("try reconnect...")
106
self.do_close()
107
self.do_connect()
108
109
110
class TransitThread(threading.Thread):
111
112
def __init__(self, *args, **kwargs):
113
# 这里会调用父类的所有有初始化方法
114
super(TransitThread, self).__init__(args=args, kwargs=kwargs)
115
self.env = args[0]
116
self.host = '172.16.109.15'
117
self.port = 54327
118
self.client = TransitClient((self.host, self.port))
119
self.client.set_read_callback(self.read_callback)
120
121
def run(self):
122
self.client.do_connect()
123
self.client.run()
124
125
def send_message(self, msg):
126
'''
127
写入消息
128
:param msg:
129
:return:
130
'''
131
self.client.write(msg)
132
133
def read_callback(self, msg):
134
'''
135
读取消息回调
136
:param msg:
137
:return:
138
'''
139
print('recved data:', msg)
140
141
142
msg_client = None
143
ats_client = None
144
interlock_client = None
145
146
147
class MsgClientModel(models.Model):
148
_name = 'metro_park_dispatch.msg_client'
149
_description = '消息收发客户端'
150
151
@api.model_cr
152
def _register_hook(self):
153
""" stuff to do right after the registry is built """
154
global msg_client
155
msg_client = TransitThread(self.env)
156
msg_client.start()
157
158
@api.model
159
def send_msg(self, msg):
160
'''
161
发送通知消息
162
:return:
163
'''
164
msg_client.send_message(msg)
165
166
167
已复制