我正在寻求实现将请求发送到服务器并检索信息的Excel RTD服务器。例如,想法如下:
用户将键入= GetDuration(“ US912828D804”)之类的参数,其中参数为ISIN代码,并会接收绑定的持续时间。在后面,excel会向python服务器发出请求-在另一台计算机上运行-在该计算机上完成所有计算。
到目前为止,我已经尝试按照示例使用Excel DNA设置excel RTD服务器:
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using System.Net.Sockets;
using System.Text;
using ExcelDna.Integration.Rtd;
namespace RTDExcel
{
[ComVisible(true)] // Required since the default template puts [assembly:ComVisible(false)] in the AssemblyInfo.cs
[ProgId(RtdExcelServer_Test.ServerProgId)] // If ProgId is not specified, change the XlCall.RTD call in the wrapper to use namespace + type name (the default ProgId)
public class RtdExcelServer_Test : ExcelRtdServer
{
public const string ServerProgId = "Test_Server_1";
List<Topic> _topics = new List<Topic>();
ServerClient serverClient = new ServerClient();
Timer timer;
int i = 0;
public void TimeServer()
{
timer = new Timer(Callback);
}
protected override bool ServerStart()
{
serverClient.ConnectToServer();
TimeServer();
return true;
}
protected override void ServerTerminate()
{
serverClient.CloseConnectionToServer();
timer.Dispose();
timer = null;
}
protected override object ConnectData(Topic topic, IList<string> topicInfo, ref bool newValues)
{
_topics.Add(topic);
timer.Change(10000, 10000);
return serverClient.AskServer("Hello");
}
protected override void DisconnectData(Topic topic)
{
_topics.Remove(topic);
timer.Change(-1, -1);
}
private void Callback(object o)
{
foreach (Topic topic in _topics)
{
i += 1;
topic.UpdateValue(serverClient.AskServer("Hello"));
}
}
}
}
public class ServerClient
{
TcpClient clientSocket = new TcpClient();
public void ConnectToServer()
{
clientSocket.Connect("127.0.0.1", 8080);
}
public string AskServer(string request)
{
NetworkStream serverStream = clientSocket.GetStream();
byte[] outStream = Encoding.ASCII.GetBytes(request);
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
byte[] inStream = new byte[10025];
serverStream.Read(inStream, 0, 75);
string response = Encoding.ASCII.GetString(inStream);
return response;
}
public void CloseConnectionToServer()
{
clientSocket.Close();
}
}
Phython服务器
import socketserver as ss
import datetime
import time
import pickle
class TCPHandler(ss.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).decode('UTF-8')
print(self.data)
tmp = str(datetime.datetime.now())
print('Sending: ' + tmp)
print('Byte Size: ' + str(sys.getsizeof(tmp)))
self.request.sendall(tmp.encode())
if __name__ == "__main__":
HOST, PORT = 'localhost', 8080
# Create the server, binding to localhost on port 9999
server = ss.TCPServer((HOST, PORT), TCPHandler)
# Activate the server; this will keep running until you
print('Server is running...')
server.serve_forever()
# interrupt the program with Ctrl-C
此示例中的主要思想是测试系统。该功能仅询问服务器当前时间,该时间是根据每个请求计算的。不幸的是,每次计时器回调时excel都会崩溃。这是正确的方法吗?
更新:
似乎问题出在python服务器中,需要循环以保持客户端更新:
class TCPHandler(ss.BaseRequestHandler):
def handle(self):
closed = False
while not closed:
try:
self.data = self.request.recv(1024).decode('UTF-8')
print(self.data[0])
if self.data[0] == 'Time':
tmp = str(datetime.datetime.now())
print('Sending: ' + tmp)
print('Byte Size: ' + str(sys.getsizeof(tmp)))
self.request.send(tmp.encode())
if self.data[0] == 'Exit':
closed = True
else:
self.request.send(str('No request.').encode())
except (KeyboardInterrupt, SystemExit):
raise
现在我遇到的问题是服务器没有从客户端接收完整的消息:我没有收到“时间”或“退出”,而只得到了“ T”或“ E”。