2010-07-27 32 views
0

我正在构建一个Rails应用程序,它需要连接到使用XML消息交换数据的自定义TCP数据服务。在功能上,这不是一个问题,但是我在设计时感觉“干净”,却遇到了麻烦。Rails w /自定义TCP数据服务

简要概述:

用户登录到Rails应用程序。在登录时,凭证将通过数据服务进行验证,并返回“上下文ID”。

请求:

<login><username>testuser</username><password>mypass</password></login> 

响应:

<reply><context_id>123456</context_id></reply> 

这context_id基本上是一个会话令牌。此用户的所有后续请求都必须在XML消息中提供此context_id。

请求:

<history><context_id>123456</context_id><start_date>1/1/2010</start_date><end_date>1/31/2010</end_date></history> 

响应:

<reply><history_item>...</history_item><history_item>..</history_item></reply> 

我已经隐藏了所有的XML建筑/在我的模型,这是工作真的很好解析。我可以将context_id存储在用户的会话中,并在我的控制器中检索它,并将它传递给模型函数。

@transactions = Transaction.find({ :context_id => 123456, :start_date => '1/1/2010', :end_date => '1/31/2010' }) 

从设计的角度来看,我有2个问题,我想解答:

  1. 薪火context_id到每个示范行动是一个有点疼痛。如果模型能够从会话本身检索到id,那将是非常好的,但我知道这打破了关注点分离规则。
  2. 有一个TcpSocket连接在每次请求时被模型创建/销毁。连接并不直接绑定到context_id,所以如果套接字可以存储在某个地方并由模型检索到,那将会很好,所以我不会为每个请求重新建立连接。

这可能听起来真的很复杂,我可能会这样做都是错误的。如果有人有任何想法,我很乐意听到他们的意见。技术细节:我正在运行Apache/mod_rails,并且我对TCP服务及其体系结构有0个控制权。

回答

1

考虑将API访问移到新类中,并将TcpSocket实例和上下文ID存储在那里。改变你的模型来与这个API访问类交谈,而不是与套接字本身交谈。

around_filter添加到您的控制器,将上下文ID拉出会话,将其存储到API访问类中,并在运行该操作后将其删除。只要你的Rails进程保持单线程,你会没事的。如果切换到多线程模型,则还需要更改API访问类以将线程本地存储中的上下文ID TcpSocket存储,并且每个线程需要一个TcpSocket

+0

我实际上已经完成了一半。我创建了一个处理通信/保持上下文的API类。我在我的模型中添加了一个with_backend方法,这基本上和around_filter做的是一样的。感谢指向around_filter的指针! – 2010-07-27 13:56:29