我觉得 安卓苹果用户 读取不了读取服务器锁定状态的session

计费方式:
搜索引擎:
建筑及装修
化工及材料
广告及包装
旅游及票务
交易总额:?-
本月佣金:?-元
今日佣金:?-元
优化师数:-名
商户数:-名
网站数:-个
关键词数:-个
您的位置:
& springboot session写进redis成功,但是另一台机器读取不到
springboot session写进redis成功,但是另一台机器读取不到
提问者:果果&&|&&
分类:其他&&|&&
浏览77次&&|&&
悬赏分:3积分
我在一个服务器(41服务器)上部署了两个程序 session可以共享,分别是两个端口(),但是部署在两台机器上(41服务器和42服务器)session就共享不了了, 谁知道为什么吗? 是不是要设置什么 redis是一台单独的服务器(43服务器)
数风流人物
两个浏览器代表两个不同的客户端,当然会有两个sessionId咯。 用户重复登录的问题可以通过注销上一个登录信息或者覆盖上一个登录的信息来解决。 由于http协议的无状态性,服务器是没法确定哪一个是你当前账号的session的... -重新读了一遍问题,发现题主的意思应该是在服务器集群下如何使两个服务器辨别同一个用户才对,我觉得可以采用共同使用同一存储中心的方式来完成。恩,对于redis了解不多,希望有大神来指正,小的不才,说错勿怪。
应用的集群部署或分布式部署,经常遇到session共享的问题,要么在nginx代理解决(比如ip hash),要么在tomcat的context.xml配置Redis。spring boot也提供了session用redis解决共享的方法。 例子完整源码,已上传github。 pom.xml [html] view plain copy org.springframework.boot spring-boot-starter-parent 1.5.2.RELEASE org.springframework.boot spring-boot-starter-web org.springframework.boot spring-boot-starter-tomcat org.springframework.boot spring-boot-starter-tomcat provided org.springframework.boot spring-boot-starter-redis 1.4.6.RELEASE org.springframework.session spring-session-data-redis application.yml的配置 [plain] view plain copy logging: config: classpath:logback.xml path: d:/logs server: port: 8080 session-timeout: 60 spring: redis: database: 0 host: 127.0.0.1 port: 6379 password: timeout: 0 pool: max-active: 8 max-wait: -1 max-idle: 8 min-idle: 0 session: store-type: none RedisSessionConfig.java [java] view plain copy package com.fei.springboot. import org.springframework.context.annotation.C import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpS @Configuration //maxInactiveIntervalInSeconds 默认是1800秒过期,这里测试修改为60秒 @EnableRedisHttpSession(maxInactiveIntervalInSeconds=60) public class RedisSessionConfig{ } 如果不需要做特殊处理,只需直接使用注解@EnableRedisHttpSession即可,打开@EnableRedisHttpSession源码,发现maxInactiveIntervalInSeconds session的过期时间默认是1800秒即30分钟,如果需要修改,注解时进行修改即可。如果想对redisSession做一些特殊处理。看@EnableRedisHttpSession源码,头部的注释,也给出了一些方案。 注解@interface EnableRedisHttpSession的源码 [java] view plain copy /* * Copyright
the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.session.data.redis.config.annotation.web. import java.lang.annotation.D import java.lang.annotation.R import java.lang.annotation.T import org.springframework.context.annotation.C import org.springframework.context.annotation.I import org.springframework.data.redis.connection.RedisConnectionF import org.springframework.session.SessionR import org.springframework.session.config.annotation.web.http.EnableSpringHttpS import org.springframework.session.data.redis.RedisFlushM /** * Add this annotation to an {@code @Configuration} class to expose the * SessionRepositoryFilter as a bean named "springSessionRepositoryFilter" and backed by * Redis. In order to leverage the annotation, a single {@link RedisConnectionFactory} * must be provided. For example:
* {@literal @Configuration}
* {@literal @EnableRedisHttpSession}
* public class RedisHttpSessionConfig {
{@literal @Bean}
public JedisConnectionFactory connectionFactory() throws Exception {
return new JedisConnectionFactory();
* * More advanced configurations can extend {@link RedisHttpSessionConfiguration} instead. * * @author Rob Winch * @since 1.0 * @see EnableSpringHttpSession */ @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({ java.lang.annotation.ElementType.TYPE }) @Documented @Import(RedisHttpSessionConfiguration.class) @Configuration public @interface EnableRedisHttpSession { int maxInactiveIntervalInSeconds() default 1800; /** * * Defines a unique namespace for keys. The value is used to isolate sessions by * changing the prefix from "spring:session:" to * "spring:session::". The default is "" such that all Redis * keys begin with "spring:session". * * * * For example, if you had an application named "Application A" that needed to keep * the sessions isolated from "Application B" you could set two different values for * the applications and they could function within the same Redis instance. * * * @return the unique namespace for keys */ String redisNamespace() default ""; /** * * Sets the flush mode for the Redis sessions. The default is ON_SAVE which only * updates the backing Redis when * {@link SessionRepository#save(org.springframework.session.Session)} is invoked. In * a web environment this happens just before the HTTP response is committed. * * * Setting the value to IMMEDIATE will ensure that the any updates to the Session are * immediately written to the Redis instance. * * * @return the {@link RedisFlushMode} to use * @since 1.1 */ RedisFlushMode redisFlushMode() default RedisFlushMode.ON_SAVE; } spring boot中的session redis配置就如此简单。 写个controller测试下 [java] view plain copy package com.fei.springboot. import javax.servlet.http.HttpServletR import org.springframework.stereotype.C import org.springframework.web.bind.annotation.RequestM import org.springframework.web.bind.annotation.ResponseB @Controller @RequestMapping("/") public class TestController { @RequestMapping(value="/getSessionId") @ResponseBody public String getSessionId(HttpServletRequest request){ Object o = request.getSession().getAttribute("springboot"); if(o == null){ o = "spring boot 牛逼了!!!有端口"+request.getLocalPort()+"生成"; request.getSession().setAttribute("springboot", o); } return "端口=" + request.getLocalPort() + " sessionId=" + request.getSession().getId() +" "+o; } } 写个启动类 [java] view plain copy package com.fei. import org.springframework.boot.SpringA import org.springframework.boot.autoconfigure.EnableAutoC import org.springframework.boot.autoconfigure.SpringBootA import org.springframework.boot.builder.SpringApplicationB import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletC import org.springframework.boot.context.embedded.EmbeddedServletContainerC import org.springframework.boot.web.support.SpringBootServletI import org.springframework.ponentS @EnableAutoConfiguration @ComponentScan(basePackages={"com.fei.springboot"}) @SpringBootApplication public class Application extends SpringBootServletInitializer implements EmbeddedServletContainerCustomizer{ @Override protected SpringApplicationBuilder configure(SpringApplicationBuilder application) { return application.sources(Application.class); } public static void main(String[] args) throws Exception { SpringApplication.run(Application.class, args); } public void customize(ConfigurableEmbeddedServletContainer configurableEmbeddedServletContainer) { // configurableEmbeddedServletContainer.setPort(9090); } } 修改application.yml中的server.port的端口为80,执行启动类,然后修改为8080,再次执行启动类。 浏览器测试 http://127.0.0.1/getSessionId 得得的结果是 [plain] view plain copy 端口=80 sessionId=3312d8db-a8dc-4df3-bc3a-628c311c0b4a spring boot 牛逼了!!!有端口80生成 http://127.0.0.1:8080/getSessionId 得到的结果是 [plain] view plain copy 端口=8080 sessionId=3312d8db-a8dc-4df3-bc3a-628c311c0b4a spring boot 牛逼了!!!有端口80生成 使用redis-client,查看 注意事项: 如果启动时发现报错: ERR Unsupported CONFIG parameter: notify-keyspace- nested exception is redis.clients.jedis.exceptions.JedisDataException 这是因为redis服务器版本和jar包版本不一致造成的。 比如说,我这用的spring-session-data-redis版本是1.3.0,到maven 仓库中查询/ 发现redis是2.8.1,看了下我用的服务器是2.6的,我立刻下载了个最新版的3.x,我是本地测试的,用window的。更换redis服务器后,不再报错了。 完整例子源码,已上传github
服务热线:400-
投诉电话:7
地址:浙江省杭州市西湖区文三路90号东部软件园科技广场315-318室
官方手机版
官方公众号
copyright 2016(版权所有 杭州志卓科技股份有限公司 浙ICP备号-86博客访问: 1109394
博文数量: 237
博客积分: 6394
博客等级: 准将
技术积分: 2573
注册时间:
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: 嵌入式
/kf/471.html
HTTP协议与状态保持
HTTP协议本身是无状态的,这与HTTP协议本来的目的是相符的,客户端只需要简单的向服务器请求下载某些文件,无论是客户端还是服务器都没有必要纪录彼此过去的行为,每一次请求之间都是独立的,好比一个顾客和一个自动售货机或者一个普通的(非会员制)大卖场之间的关系一样。
&&& 然而聪明(或者贪心?)的人们很快发现如果能够提供一些按需生成的动态信息会使web变得更加有用,就像给有线电视加上点播功能一样。这种需求一方面迫使HTML逐步添加了表单、脚本、DOM等客户端行为,另一方面在服务器端则出现了CGI规范以响应客户端的动态请求,作为传输载体的HTTP协议也添加了文件上载、cookie这些特性。其中cookie的作用就是为了解决HTTP协议无状态的缺陷所作出的努力。至于后来出现的session机制则是又一种在客户端与服务器之间保持状态的解决方案。
&&& 让我们用几个例子来描述一下cookie和session机制之间的区别与联系。笔者曾经常去的一家咖啡店有喝5杯咖啡免费赠一杯咖啡的优惠,然而一次性消费5杯咖啡的机会微乎其微,这时就需要某种方式来纪录某位顾客的消费数量。想象一下其实也无外乎下面的几种方案:
&&& 1、该店的店员很厉害,能记住每位顾客的消费数量,只要顾客一走进咖啡店,店员就知道该怎么对待了。这种做法就是协议本身支持状态。
&&& 2、发给顾客一张卡片,上面记录着消费的数量,一般还有个有效期限。每次消费时,如果顾客出示这张卡片,则此次消费就会与以前或以后的消费相联系起来。这种做法就是在客户端保持状态。
&&& 3、发给顾客一张会员卡,除了卡号之外什么信息也不纪录,每次消费时,如果顾客出示该卡片,则店员在店里的纪录本上找到这个卡号对应的纪录添加一些消费信息。这种做法就是在服务器端保持状态。
&&& 由于HTTP协议是无状态的,而出于种种考虑也不希望使之成为有状态的,因此,后面两种方案就成为现实的选择。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。
http://www.blogjava.net/cheneyfree/archive//120168.html
Cookie 定义
typedef struct CookieEntry
&&&&&& PTCHAR&&&& pszN
&&&&&& PTCHAR&&&& pszV
&&&&&& PTCHAR&&&& pszUrlP
&&&&&& DWORD&&&&& dwF//Security Flags
&&&&&& DWORD&&&&& dwLowWordE//LowWord of FILETIME
&&&&&& DWORD&&&&& dwHighWordE//HighWord ofFILETIME
&&&&&& DWORD&&&&& dwLowWordC//LowWord of FILETIME
&&&&&& DWORD&&&&& dwHighWordC//HighWord of FILETIME
&&&&&& CHAR&& chE//'*'
}COOKIEENTRY, *LPCOOKIEENTRY;
总结起来,每个Cookie有6个属性,分别 为:Cookies Name; Cookies Value; Domain;Path; Secure; Expire Date。这里给出的Cookie的6个属性和C++中定义的结构体不完全一致。其原因将在Cookie的文件格式小节给出解释。
下面对Cookie结构中的各个属性分别给出解释:
Cookies Name &Key&, 必要属性,指明了Cookie的名字,有一系列字符(不包括括号、逗号、空格等)组成;每个cookie由一个唯一的名称代表,这个名称可以包含字母、数 字、下划线。Cookie的名称是不分大小写,所以mycookie和MyCookie是一样。但考虑到服务器端语言可能区分大小写,所以对程序开发者来 说定义和使用时最好还是区分大小写。
Cookies Value,&Value&Cookie 的值,Web服务器储存在Cookie中的信息;保存在Cookie中的字符串值。这个值在存储之前是用encodeURIComponent()对其进 行编码的,否则会丢失数据或占用了Cookie。而且Cookie名字和值加起来的字节数不能超过4095字节,也即4KB。
Domain, 可选,指明了Cookie的有效域的范围,默认的是产生Cookie的服务器的名字;出于安全考虑,网站不能访问由其他域所创建的Cookie。创建 Cookie以后,域的信息会作为cookie的一部分存储下来。关于域,举个例子来说,如/view /index.html, 它的域为:。这里不做详述,后面的章节会有所涉及。
Path, 可选,指明了Cookie在有效域中的有效路径,在有效路径外的网页不可以读写Cookie,默认的是产生此Cookie的信息的URL;而该属性也是 Cookie的另一个安全特征,限制对Web服务器上特定目录的访问。即控制哪些访问能触发发送。例如请求的地址是上面的URL,如果 path=/view,这个Cookie就会被发送,但是path为其他路径的话,该Cookie会被忽略。
Secure, 可选,一个true/false值,用于表示Cookie是否只能从安全网站(使用SSL和https协议的网站)中访问;即如果标记一个Cookie为 安全的(这个值被设置为true),那么仅当客户端与服务器的对话通道是安全的(如HTTP over SSL),Cookie才会被传送。
Expire Date, 可选,指明了Cookie的有效时间,一旦过期,Cookie将不再有效,通常由产生Cookie的程序(Date由服务器指明)指定,如果不指明,系统会默认Cookie将在用户会话结束后自动过期。
cookie机制和session机制的区别
*************************************************************************************
Cookie是客户端的存储空间,由浏览器来维持。具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于才服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制("PHPSESSID")来达到保存标识的目的,但实际上还有其他选择,比如说重写URL和隐藏表单域。
如何利用实现自动登录
*************************************************************************************
当用户在某个网站注册后,就会收到服务器发送的一个惟一用户ID的cookie。客户后来重新连接时,这个用户ID会自动发送回服务器,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户务需给出明确的用户名和密码,就可以访问服务器上的资源。
如何根据用户的爱好定制站点
*************************************************************************************
网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。
通过Cookie实现Session保持
/blog/1663113
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
public class MyHttpClient implements InetConfig {
private DefaultHttpClient httpClient;
private HttpPost httpPost;
private HttpEntity httpEntity;
private HttpResponse httpResponse;
public static String PHPSESSID = null;
public LVHttpClient() {
public String executeRequest(String path, List&NameValuePair& params) {
&&&&&&&&String ret = "none";
&&&&&& try {
&&&&&&&&&&& this.httpPost = new HttpPost(BASEPATH + path);
&&&&&&&&&&&&httpEntity = new UrlEncodedFormEntity(params, HTTP.UTF_8);
&&&&&&&&&&&&httpPost.setEntity(httpEntity);
&&&&&&&&&&&& //第一次一般是还未被赋值,若有值则将SessionId发给服务器
&&&&&&&&&&&&if(null != PHPSESSID){
&&&&&&&&&&&&&&&&httpPost.setHeader("Cookie", "PHPSESSID=" + PHPSESSID);
&&&&&&&&&&&&}
&&&&&&&&&&&&httpClient = new DefaultHttpClient();
&&&&&&&&} catch (UnsupportedEncodingException e) {
&&&&&&&&&&&&e.printStackTrace();
&&&&&&& try {
&&&&&&&&&&&&httpResponse = httpClient.execute(httpPost);
&&&&&&&&&&& if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
&&&&&&&&&&&&&&&&HttpEntity entity = httpResponse.getEntity();
&&&&&&&&&&&&&&&&ret = EntityUtils.toString(entity);
&&&&&&&&&&&&&&&&CookieStore mCookieStore = httpClient.getCookieStore();
&&&&&&&&&&&&&&&&List&Cookie& cookies = mCookieStore.getCookies();
&&&&&&&&&&&&&&& for (int i = 0; i & cookies.size(); i++) {
&&&&&&&&&&&&&&&&&&&& //这里是读取Cookie['PHPSESSID']的值存在静态变量中,保证每次都是同一个值
&&&&&&&&&&&&&&&&&&&& if ("PHPSESSID".equals(cookies.get(i).getName())) {
&&&&&&&&&&&&&&&&&&&&&&&&PHPSESSID = cookies.get(i).getValue();
&&&&&&&&&&&&&&&&&&&&&&& break;
&&&&&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&&&&&}
&&&&&&&&&&&&}
&&&&&&&&} catch (ClientProtocolException e) {
&&&&&&&&&&&&e.printStackTrace();
&&&&&&&&} catch (IOException e) {
&&&&&&&&&&&&e.printStackTrace();
&&&&&&& return ret;
基于http协议的,那么如果网站不是php做的话,那个叫做Sessionid的Cookie可能叫做别的了,就不是PHPSESSID了,而是叫做别的名字了,这个可能要具体情况去查了。
HTTP协议分析:
http://blog.csdn.net/gueter/article/details/1524447
阅读(12665) | 评论(0) | 转发(0) |
相关热门文章
给主人留下些什么吧!~~
请登录后评论。再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
威锋网7月10日消锋网7月10日消息,《植物大战僵尸2》 如今...
威锋网7月10日消息,《植物大...
近日,开发商 Esquilax Games ..
说到方块游戏,相信有很多朋友应该还会记得 Gavina Games 早...
威锋网7月10日消息,《植物大...
近日,开发商 Esquilax Games ..
说到方块游戏,相信有很多朋友应该还会记得 Gavina Games 早...
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
再吸金!SE推出《最终幻想:全员勇者》钥匙扣
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!

我要回帖

更多关于 网页读取服务器上的游戏 的文章

 

随机推荐