我最近遇到了一个类似的问题,想在 Rails 和 Erlang 应用程序之间共享会话数据。我的解决方案是编写一个Rack::Session::Abstract::ID
类,将 Redis 中的会话存储为哈希值。它不调用Marshal.dump
类型String
。这允许非 ruby 应用程序使用某些会话值(如果它们具有session_id
.
require 'rack/session/abstract/id'
class MaybeMarshalRedisSession < Rack::Session::Abstract::ID
def initialize(app, options = {})
@redis = options.delete(:redis) || Redis.current
@expiry = options[:expire_after] ||= (60 * 60 * 24)
@prefix = options[:key] || 'rack.session'
@session_key = "#{@prefix}:%s"
super
end
def get_session(env, sid)
sid ||= generate_sid
session = @redis.hgetall(@session_key % sid)
session.each_pair do |key, value|
session[key] = begin
Marshal.load(value)
rescue TypeError
value
end
end
[sid, session]
end
def set_session(env, sid, session, options={})
@redis.multi do
session.each_pair do |key, value|
# keep string values bare so other languages can read them
value = value.is_a?(String) ? value : Marshal.dump(value)
@redis.hset(@session_key % sid, key, value)
end
@redis.expire(@session_key % sid, @expiry)
end
sid
end
def destroy_session(env, sid, option={})
@redis.del(@session_key % sid)
generate_sid unless options[:drop]
end
end
您可以从 rails 使用它:
MyApp::Application.config.session_store MaybeMarshalRedisSession
从机架:
use MaybeMarshalRedisSession
并从其他地方:
redis.hgetall("rack.session:#{session_id}")
如果您想从 MainApp 或 Node.js 调用 PhotoApp,您可以发出包含用户会话 cookie 的 HTTP 请求。