├── logs ├── error ├── info_2018-09-02.log ├── logs_2018-09-02.log ├── error_2017-03-08.log ├── error_2017-03-06.log ├── logs_2017-03-12.log ├── info ├── logs ├── info_2018-09-01.log ├── logs_2018-09-01.log ├── logs_2017-03-08.log ├── error_2017-10-22.log ├── logs_2017-03-06.log └── logs_2017-03-07.log ├── .DS_Store ├── out ├── start.bat ├── restart.bat ├── .DS_Store ├── syncklines.bat ├── stocksocketclient.jar └── config.properties ├── libs ├── mail.jar ├── org.json.jar ├── gson-2.2.4.jar ├── jedis-2.8.1.jar ├── log4j-1.2.17.jar ├── httpcore-4.4.4.jar ├── pinyin4j-2.5.0.jar ├── xSocket-2.8.15.jar ├── commons-codec-1.9.jar ├── commons-email-1.4.jar ├── httpclient-4.5.2.jar ├── slf4j-api-1.7.22.jar ├── commons-logging-1.2.jar ├── httpclient-win-4.5.2.jar ├── slf4j-log4j12-1.7.22.jar ├── httpclient-cache-4.5.2.jar ├── mysql-connector-java-5.1.38-bin.jar └── org.springframework.web-3.0.0.M4.jar ├── src ├── .DS_Store ├── com │ ├── .DS_Store │ └── dangfm │ │ ├── .DS_Store │ │ └── stock │ │ ├── .DS_Store │ │ └── socketclient │ │ ├── .DS_Store │ │ ├── server │ │ ├── StockClientHeart.java │ │ ├── StockClientHandle.java │ │ ├── StockClientThread.java │ │ └── StockResposeDatas.java │ │ ├── utils │ │ ├── HtmlUtil.java │ │ ├── FileHelper.java │ │ ├── RedisCls.java │ │ ├── ZipUtils.java │ │ └── HttpWebCollecter.java │ │ ├── user │ │ └── UserHelper.java │ │ ├── Main.java │ │ ├── market │ │ ├── SaveKlineDatas.java │ │ ├── SaveAllStocks.java │ │ ├── CreateMinuteKline.java │ │ ├── CreateTimeLine.java │ │ ├── GetStockDaysLine.java │ │ └── InitAllStockDatas.java │ │ └── Config.java ├── META-INF │ └── MANIFEST.MF ├── config.properties └── log4j.properties ├── META-INF └── MANIFEST.MF ├── .idea ├── vcs.xml ├── misc.xml ├── modules.xml ├── artifacts │ ├── config_properties.xml │ └── stocksocketclient_jar.xml ├── libraries │ └── libs.xml └── stocksocketclient.iml ├── stocksocketclient.iml └── README.md /logs/error: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/.DS_Store -------------------------------------------------------------------------------- /out/start.bat: -------------------------------------------------------------------------------- 1 | java -jar D:/wwwroot/stockSync/stockClient/stocksocketclient.jar -------------------------------------------------------------------------------- /out/restart.bat: -------------------------------------------------------------------------------- 1 | java -jar D:/wwwroot/stockSync/stockClient/stocksocketclient.jar 1 -------------------------------------------------------------------------------- /libs/mail.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/mail.jar -------------------------------------------------------------------------------- /out/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/out/.DS_Store -------------------------------------------------------------------------------- /out/syncklines.bat: -------------------------------------------------------------------------------- 1 | java -jar D:/wwwroot/stockSync/stockClient/stocksocketclient.jar 3 -------------------------------------------------------------------------------- /src/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/src/.DS_Store -------------------------------------------------------------------------------- /libs/org.json.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/org.json.jar -------------------------------------------------------------------------------- /src/com/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/src/com/.DS_Store -------------------------------------------------------------------------------- /libs/gson-2.2.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/gson-2.2.4.jar -------------------------------------------------------------------------------- /libs/jedis-2.8.1.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/jedis-2.8.1.jar -------------------------------------------------------------------------------- /libs/log4j-1.2.17.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/log4j-1.2.17.jar -------------------------------------------------------------------------------- /META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.dangfm.stock.socketclient.Main 3 | 4 | -------------------------------------------------------------------------------- /libs/httpcore-4.4.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/httpcore-4.4.4.jar -------------------------------------------------------------------------------- /libs/pinyin4j-2.5.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/pinyin4j-2.5.0.jar -------------------------------------------------------------------------------- /libs/xSocket-2.8.15.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/xSocket-2.8.15.jar -------------------------------------------------------------------------------- /src/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: com.dangfm.stock.socketclient.Main 3 | 4 | -------------------------------------------------------------------------------- /src/com/dangfm/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/src/com/dangfm/.DS_Store -------------------------------------------------------------------------------- /libs/commons-codec-1.9.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/commons-codec-1.9.jar -------------------------------------------------------------------------------- /libs/commons-email-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/commons-email-1.4.jar -------------------------------------------------------------------------------- /libs/httpclient-4.5.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/httpclient-4.5.2.jar -------------------------------------------------------------------------------- /libs/slf4j-api-1.7.22.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/slf4j-api-1.7.22.jar -------------------------------------------------------------------------------- /out/stocksocketclient.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/out/stocksocketclient.jar -------------------------------------------------------------------------------- /libs/commons-logging-1.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/commons-logging-1.2.jar -------------------------------------------------------------------------------- /libs/httpclient-win-4.5.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/httpclient-win-4.5.2.jar -------------------------------------------------------------------------------- /libs/slf4j-log4j12-1.7.22.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/slf4j-log4j12-1.7.22.jar -------------------------------------------------------------------------------- /libs/httpclient-cache-4.5.2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/httpclient-cache-4.5.2.jar -------------------------------------------------------------------------------- /src/com/dangfm/stock/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/src/com/dangfm/stock/.DS_Store -------------------------------------------------------------------------------- /logs/info_2018-09-02.log: -------------------------------------------------------------------------------- 1 | 2018-09-02 05:59:58 [ xNbcPool-1-thread-3:36234270 ] - [ INFO ] 客户端断开行情服务器:114.55.140.140:9099 2 | -------------------------------------------------------------------------------- /logs/logs_2018-09-02.log: -------------------------------------------------------------------------------- 1 | 2018-09-02 05:59:58 [ xNbcPool-1-thread-3:36234270 ] - [ INFO ] 客户端断开行情服务器:114.55.140.140:9099 2 | -------------------------------------------------------------------------------- /libs/mysql-connector-java-5.1.38-bin.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/mysql-connector-java-5.1.38-bin.jar -------------------------------------------------------------------------------- /libs/org.springframework.web-3.0.0.M4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/libs/org.springframework.web-3.0.0.M4.jar -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dangfm/stocksoketclient/HEAD/src/com/dangfm/stock/socketclient/.DS_Store -------------------------------------------------------------------------------- /logs/error_2017-03-08.log: -------------------------------------------------------------------------------- 1 | 2017-03-08 04:21:43 [ pool-1-thread-1:124008586 ] - [ ERROR ] Network is down 2 | 2017-03-08 05:01:28 [ pool-1-thread-1:126394126 ] - [ ERROR ] Network is down 3 | -------------------------------------------------------------------------------- /logs/error_2017-03-06.log: -------------------------------------------------------------------------------- 1 | 2017-03-06 17:30:44 [ main:275 ] - [ ERROR ] redis 127.0.0.1:6379 disconnected 2 | 2017-03-06 17:30:44 [ main:277 ] - [ ERROR ] redis 127.0.0.1:6379 disconnected 3 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/artifacts/config_properties.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/ 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /out/config.properties: -------------------------------------------------------------------------------- 1 | # 本地redis 2 | redisServer = 127.0.0.1 3 | redisPort = 6379 4 | redisPassword = 5 | 6 | #路由 7 | socketServer = http://119.45.134.19:8111/v1/ 8 | 9 | #是否采集K线历史数据 10 | isCollectionHistoryKline = false 11 | #是否采集分钟K线历史数据 12 | isCollectionHistoryMinKline = false 13 | #是否采集分钟K线复权数据 14 | isCollectionHistoryMinKline_fq = false 15 | # k线保存地址 16 | klineSavePath = 17 | 18 | -------------------------------------------------------------------------------- /src/config.properties: -------------------------------------------------------------------------------- 1 | # 本地redis 2 | redisServer = 127.0.0.1 3 | redisPort = 6379 4 | redisPassword = 5 | 6 | #路由 7 | socketServer = http://119.45.134.19:8111/v1/ 8 | 9 | #是否采集K线历史数据 10 | isCollectionHistoryKline = false 11 | #是否采集分钟K线历史数据 12 | isCollectionHistoryMinKline = false 13 | #是否采集分钟K线复权数据 14 | isCollectionHistoryMinKline_fq = false 15 | # k线保存地址 16 | klineSavePath = 17 | 18 | -------------------------------------------------------------------------------- /.idea/libraries/libs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/stocksocketclient.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /logs/logs_2017-03-12.log: -------------------------------------------------------------------------------- 1 | 2017-03-12 11:39:56 [ main:0 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 2 | 2017-03-12 11:39:56 [ main:4 ] - [ INFO ] OS Name=Mac OS X 3 | 2017-03-12 11:39:56 [ main:5 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 4 | 2017-03-12 11:39:56 [ main:5 ] - [ INFO ] 当前最大可用内存:1820 M 5 | 2017-03-12 11:39:56 [ main:221 ] - [ INFO ] redis 127.0.0.1:6379 connected! 6 | 2017-03-12 11:39:56 [ main:222 ] - [ INFO ] redis 127.0.0.1:6379 connected! 7 | -------------------------------------------------------------------------------- /stocksocketclient.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /logs/info: -------------------------------------------------------------------------------- 1 | 2018-09-19 10:49:16 [ xNbcPool-1-thread-1:0 ] - [ INFO ] 客户端启动成功连接行情服务器:114.55.140.140:9099 2 | 2018-09-19 10:49:16 [ xNbcPool-1-thread-1:18 ] - [ INFO ] **********成功注册大师兄(dashixiong.cn)行情服务,以下是您的注册资料,请妥善保存。********** 3 | 2018-09-19 10:49:16 [ xNbcPool-1-thread-1:33 ] - [ INFO ] {"app_key":"87a600f0faf746eba5a6e235c3b34d44","app_password":"6RZxYG","app_id":1036,"app_secret":"5c48369af06f4d58909eee5b7f19cebe"} 4 | 2018-09-19 10:49:17 [ xNbcPool-1-thread-1:1074 ] - [ INFO ] **********欢迎访问大师兄(dashixiong.cn)行情数据服务 v1.0.1********** 5 | 2018-09-19 10:49:17 [ Thread-11:1131 ] - [ INFO ] 开始初始化数据... 6 | 2018-09-19 10:49:28 [ Thread-11:12373 ] - [ INFO ] 初始化所有股票板块分类数据-完成,用时:147ms 7 | 2018-09-19 10:49:31 [ Thread-11:15129 ] - [ INFO ] 初始化所有股票数据-完成,用时:2756ms 8 | 2018-09-19 10:49:33 [ Thread-11:17438 ] - [ INFO ] 初始化所有股票搜索库数据-完成,用时:2309ms 9 | 2018-09-19 10:49:36 [ Thread-11:20055 ] - [ INFO ] 初始化所有股票实时行情数据-完成,用时:2617ms 10 | 2018-09-19 10:49:37 [ Thread-11:21452 ] - [ INFO ] 初始化所有股票财务数据-完成,用时:1396ms 11 | 2018-09-19 10:49:44 [ Thread-11:28228 ] - [ INFO ] 初始化所有股票除权数据-完成,用时:6776ms 12 | -------------------------------------------------------------------------------- /logs/logs: -------------------------------------------------------------------------------- 1 | 2018-09-19 10:49:16 [ xNbcPool-1-thread-1:0 ] - [ INFO ] 客户端启动成功连接行情服务器:114.55.140.140:9099 2 | 2018-09-19 10:49:16 [ xNbcPool-1-thread-1:18 ] - [ INFO ] **********成功注册大师兄(dashixiong.cn)行情服务,以下是您的注册资料,请妥善保存。********** 3 | 2018-09-19 10:49:16 [ xNbcPool-1-thread-1:33 ] - [ INFO ] {"app_key":"87a600f0faf746eba5a6e235c3b34d44","app_password":"6RZxYG","app_id":1036,"app_secret":"5c48369af06f4d58909eee5b7f19cebe"} 4 | 2018-09-19 10:49:17 [ xNbcPool-1-thread-1:1074 ] - [ INFO ] **********欢迎访问大师兄(dashixiong.cn)行情数据服务 v1.0.1********** 5 | 2018-09-19 10:49:17 [ Thread-11:1131 ] - [ INFO ] 开始初始化数据... 6 | 2018-09-19 10:49:28 [ Thread-11:12373 ] - [ INFO ] 初始化所有股票板块分类数据-完成,用时:147ms 7 | 2018-09-19 10:49:31 [ Thread-11:15129 ] - [ INFO ] 初始化所有股票数据-完成,用时:2756ms 8 | 2018-09-19 10:49:33 [ Thread-11:17438 ] - [ INFO ] 初始化所有股票搜索库数据-完成,用时:2309ms 9 | 2018-09-19 10:49:36 [ Thread-11:20055 ] - [ INFO ] 初始化所有股票实时行情数据-完成,用时:2617ms 10 | 2018-09-19 10:49:37 [ Thread-11:21452 ] - [ INFO ] 初始化所有股票财务数据-完成,用时:1396ms 11 | 2018-09-19 10:49:44 [ Thread-11:28228 ] - [ INFO ] 初始化所有股票除权数据-完成,用时:6776ms 12 | -------------------------------------------------------------------------------- /src/log4j.properties: -------------------------------------------------------------------------------- 1 | ### #配置根Logger ### 2 | log4j.rootLogger=debug,stdout,D,E,I 3 | 4 | ### 输出到控制台 ### 5 | log4j.appender.stdout=org.apache.log4j.ConsoleAppender 6 | log4j.appender.stdout.Target=System.out 7 | log4j.appender.stdout.layout=org.apache.log4j.PatternLayout 8 | log4j.appender.stdout.layout.ConversionPattern=%d{yyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n 9 | #log4j.appender.console.layout.ConversionPattern=%5p [%t] (%F:%L) %d{HH:mm:ss,SSS} -- %m%n 10 | 11 | log4j.appender.E = org.apache.log4j.DailyRollingFileAppender 12 | log4j.appender.E.File = logs/logs 13 | log4j.appender.E.DatePattern='_'yyyy-MM-dd'.log' 14 | log4j.appender.E.Append = true 15 | log4j.appender.E.Threshold = DEBUG 16 | log4j.appender.E.layout = org.apache.log4j.PatternLayout 17 | log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n 18 | 19 | log4j.appender.D = org.apache.log4j.DailyRollingFileAppender 20 | log4j.appender.D.File = logs/error 21 | log4j.appender.D.DatePattern='_'yyyy-MM-dd'.log' 22 | log4j.appender.D.Append = true 23 | log4j.appender.D.Threshold = ERROR 24 | log4j.appender.D.layout = org.apache.log4j.PatternLayout 25 | log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n 26 | 27 | log4j.appender.I = org.apache.log4j.DailyRollingFileAppender 28 | log4j.appender.I.File = logs/info 29 | log4j.appender.I.DatePattern='_'yyyy-MM-dd'.log' 30 | log4j.appender.I.Append = true 31 | log4j.appender.I.Threshold = INFO 32 | log4j.appender.I.layout = org.apache.log4j.PatternLayout 33 | log4j.appender.I.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n 34 | # -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/server/StockClientHeart.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.server; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.utils.FN; 5 | import org.json.JSONObject; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import org.xsocket.connection.INonBlockingConnection; 9 | 10 | import java.io.IOException; 11 | import java.util.concurrent.Executors; 12 | import java.util.concurrent.ScheduledExecutorService; 13 | 14 | public class StockClientHeart extends Thread { 15 | public static final Logger logger = LoggerFactory.getLogger(StockClientHeart.class); 16 | private static int loopTime = 30000; // 10秒一次 17 | 18 | private static INonBlockingConnection nbc; 19 | 20 | private boolean isStart = true; 21 | 22 | /** 23 | * 定时任务运行池 24 | */ 25 | private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(10); 26 | 27 | 28 | public static void StockClientHeart(INonBlockingConnection nbcs){ 29 | nbc = nbcs; 30 | // logger.info("******启动心跳******"); 31 | FN.createExecutor("0", loopTime, heart(), true,executor); 32 | } 33 | 34 | 35 | private static Runnable heart(){ 36 | return new Runnable(){ 37 | @Override 38 | public void run() { 39 | if(nbc.isOpen()){ 40 | try { 41 | nbc.write(FN.dataForWrite(Config.protocol_heart,new JSONObject())); 42 | // logger.info("******心跳******"); 43 | } catch (IOException e) { 44 | logger.info(e.toString()); 45 | } 46 | } 47 | } 48 | }; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /.idea/artifacts/stocksocketclient_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/ 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/utils/HtmlUtil.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.utils; 2 | import java.util.regex.Matcher; 3 | import java.util.regex.Pattern; 4 | 5 | /** 6 | * Html工具箱 7 | * Created by dangfm on 16/3/19. 8 | */ 9 | 10 | 11 | public class HtmlUtil { 12 | private static final String regEx_script = "]*?>[\\s\\S]*?<\\/script>"; // 定义script的正则表达式 13 | private static final String regEx_style = "]*?>[\\s\\S]*?<\\/style>"; // 定义style的正则表达式 14 | private static final String regEx_html = "<[^>]+>"; // 定义HTML标签的正则表达式 15 | private static final String regEx_space = "\\s*|\t|\r|\n";//定义空格回车换行符 16 | 17 | /** 18 | * @param htmlStr 19 | * @return 20 | * 删除Html标签 21 | */ 22 | public static String delHTMLTag(String htmlStr) { 23 | Pattern p_script = Pattern.compile(regEx_script, Pattern.CASE_INSENSITIVE); 24 | Matcher m_script = p_script.matcher(htmlStr); 25 | htmlStr = m_script.replaceAll(""); // 过滤script标签 26 | 27 | Pattern p_style = Pattern.compile(regEx_style, Pattern.CASE_INSENSITIVE); 28 | Matcher m_style = p_style.matcher(htmlStr); 29 | htmlStr = m_style.replaceAll(""); // 过滤style标签 30 | 31 | Pattern p_html = Pattern.compile(regEx_html, Pattern.CASE_INSENSITIVE); 32 | Matcher m_html = p_html.matcher(htmlStr); 33 | htmlStr = m_html.replaceAll(""); // 过滤html标签 34 | 35 | Pattern p_space = Pattern.compile(regEx_space, Pattern.CASE_INSENSITIVE); 36 | Matcher m_space = p_space.matcher(htmlStr); 37 | htmlStr = m_space.replaceAll(""); // 过滤空格回车标签 38 | return htmlStr.trim(); // 返回文本字符串 39 | } 40 | 41 | public static String getTextFromHtml(String htmlStr){ 42 | htmlStr = delHTMLTag(htmlStr); 43 | htmlStr = htmlStr.replaceAll(" ", ""); 44 | htmlStr = htmlStr.substring(0, htmlStr.indexOf("。")+1); 45 | return htmlStr; 46 | } 47 | 48 | /** 49 | * 正则提取 50 | * @param patternStr 51 | * @param string 52 | * @return 53 | */ 54 | public static Matcher regStr(String patternStr,String string){ 55 | Pattern pattern = Pattern.compile(patternStr); 56 | Matcher matcher = pattern.matcher(string); 57 | return matcher; 58 | } 59 | 60 | } -------------------------------------------------------------------------------- /logs/info_2018-09-01.log: -------------------------------------------------------------------------------- 1 | 2018-04-23 01:04:24 [ main:0 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 2 | 2018-04-23 01:04:24 [ main:5 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 3 | 2018-04-23 01:04:24 [ main:6 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 4 | 2018-04-23 01:04:24 [ main:7 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 5 | 2018-04-23 01:04:24 [ main:14 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 6 | 2018-04-23 01:04:24 [ main:15 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 7 | 2018-04-23 01:04:24 [ main:16 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 8 | 2018-04-23 01:04:24 [ main:17 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 9 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1094 ] - [ INFO ] 客户端启动成功连接行情服务器:114.55.140.140:9099 10 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1221 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 11 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1221 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 12 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1225 ] - [ INFO ] **********成功注册大师兄(dashixiong.cn)行情服务,以下是您的注册资料,请妥善保存。********** 13 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1254 ] - [ INFO ] {"app_key":"b9dbb4097f1c4a018f92030ce17c4cdb","app_password":"PZ1zYJ","app_id":1010,"app_secret":"e20616459e8348ef9234ca4342a6fc1d"} 14 | 2018-09-01 19:56:04 [ xNbcPool-1-thread-1:0 ] - [ INFO ] 客户端启动成功连接行情服务器:114.55.140.140:9099 15 | 2018-09-01 19:56:04 [ xNbcPool-1-thread-1:6 ] - [ INFO ] **********成功注册大师兄(dashixiong.cn)行情服务,以下是您的注册资料,请妥善保存。********** 16 | 2018-09-01 19:56:04 [ xNbcPool-1-thread-1:20 ] - [ INFO ] {"app_key":"2b48345281a449d5be601a20456ada6b","app_password":"zawgXc","app_id":1023,"app_secret":"d4ab3ee6053545c598e43cc1cdac43e3"} 17 | 2018-09-01 19:56:05 [ xNbcPool-1-thread-2:1050 ] - [ INFO ] **********欢迎访问大师兄(dashixiong.cn)行情数据服务 v1.0********** 18 | 2018-09-01 19:56:05 [ Thread-11:1068 ] - [ INFO ] 开始初始化数据... 19 | 2018-09-01 19:56:16 [ Thread-11:12134 ] - [ INFO ] 初始化所有股票板块分类数据-完成,用时:62ms 20 | 2018-09-01 19:56:17 [ Thread-11:13576 ] - [ INFO ] 初始化所有股票数据-完成,用时:1442ms 21 | 2018-09-01 19:56:18 [ Thread-11:14438 ] - [ INFO ] 初始化所有股票搜索库数据-完成,用时:861ms 22 | 2018-09-01 19:56:21 [ Thread-11:17554 ] - [ INFO ] 初始化所有股票实时行情数据-完成,用时:3116ms 23 | 2018-09-01 20:00:00 [ pool-1-thread-2:235701 ] - [ INFO ] 未开启采集K线开关,如需采集历史K线数据请设置配置文件 isCollectionHistoryKline=true 24 | -------------------------------------------------------------------------------- /logs/logs_2018-09-01.log: -------------------------------------------------------------------------------- 1 | 2018-04-23 01:04:24 [ main:0 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 2 | 2018-04-23 01:04:24 [ main:5 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 3 | 2018-04-23 01:04:24 [ main:6 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 4 | 2018-04-23 01:04:24 [ main:7 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 5 | 2018-04-23 01:04:24 [ main:14 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 6 | 2018-04-23 01:04:24 [ main:15 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 7 | 2018-04-23 01:04:24 [ main:16 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 8 | 2018-04-23 01:04:24 [ main:17 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 9 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1094 ] - [ INFO ] 客户端启动成功连接行情服务器:114.55.140.140:9099 10 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1221 ] - [ ERROR ] redis:127.0.0.1:6379 unconnected! 11 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1221 ] - [ ERROR ] redis.clients.jedis.exceptions.JedisConnectionException: java.net.ConnectException: Connection refused (Connection refused) 12 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1225 ] - [ INFO ] **********成功注册大师兄(dashixiong.cn)行情服务,以下是您的注册资料,请妥善保存。********** 13 | 2018-04-23 01:04:25 [ xNbcPool-1-thread-1:1254 ] - [ INFO ] {"app_key":"b9dbb4097f1c4a018f92030ce17c4cdb","app_password":"PZ1zYJ","app_id":1010,"app_secret":"e20616459e8348ef9234ca4342a6fc1d"} 14 | 2018-09-01 19:56:04 [ xNbcPool-1-thread-1:0 ] - [ INFO ] 客户端启动成功连接行情服务器:114.55.140.140:9099 15 | 2018-09-01 19:56:04 [ xNbcPool-1-thread-1:6 ] - [ INFO ] **********成功注册大师兄(dashixiong.cn)行情服务,以下是您的注册资料,请妥善保存。********** 16 | 2018-09-01 19:56:04 [ xNbcPool-1-thread-1:20 ] - [ INFO ] {"app_key":"2b48345281a449d5be601a20456ada6b","app_password":"zawgXc","app_id":1023,"app_secret":"d4ab3ee6053545c598e43cc1cdac43e3"} 17 | 2018-09-01 19:56:05 [ xNbcPool-1-thread-2:1050 ] - [ INFO ] **********欢迎访问大师兄(dashixiong.cn)行情数据服务 v1.0********** 18 | 2018-09-01 19:56:05 [ Thread-11:1068 ] - [ INFO ] 开始初始化数据... 19 | 2018-09-01 19:56:16 [ Thread-11:12134 ] - [ INFO ] 初始化所有股票板块分类数据-完成,用时:62ms 20 | 2018-09-01 19:56:17 [ Thread-11:13576 ] - [ INFO ] 初始化所有股票数据-完成,用时:1442ms 21 | 2018-09-01 19:56:18 [ Thread-11:14438 ] - [ INFO ] 初始化所有股票搜索库数据-完成,用时:861ms 22 | 2018-09-01 19:56:21 [ Thread-11:17554 ] - [ INFO ] 初始化所有股票实时行情数据-完成,用时:3116ms 23 | 2018-09-01 20:00:00 [ pool-1-thread-2:235701 ] - [ INFO ] 未开启采集K线开关,如需采集历史K线数据请设置配置文件 isCollectionHistoryKline=true 24 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/user/UserHelper.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.user; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.server.StockClientThread; 5 | import com.dangfm.stock.socketclient.utils.FN; 6 | import org.json.JSONException; 7 | import org.json.JSONObject; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | import org.xsocket.connection.INonBlockingConnection; 11 | import org.xsocket.connection.NonBlockingConnection; 12 | 13 | import java.io.IOException; 14 | import java.nio.channels.ClosedChannelException; 15 | import java.util.Scanner; 16 | 17 | import static java.lang.Thread.sleep; 18 | 19 | public final class UserHelper { 20 | public static final Logger logger = LoggerFactory.getLogger(UserHelper.class); 21 | /** 22 | * 启动注册 23 | */ 24 | public static void register(String msg,INonBlockingConnection nbc){ 25 | if (msg.startsWith("{")) { 26 | JSONObject subObj = null; 27 | try { 28 | subObj = new JSONObject(msg); 29 | String app_key = subObj.getString("app_key"); 30 | String app_secret = subObj.getString("app_secret"); 31 | String app_id = subObj.getString("app_id"); 32 | String app_password = subObj.getString("app_password"); 33 | 34 | // 35 | FN.setProperty("appKey",app_key); 36 | FN.setProperty("appSecret",app_secret); 37 | FN.setProperty("appId",app_id); 38 | FN.setProperty("appPassword",app_password); 39 | 40 | Config.appKey=app_key; 41 | Config.appSecret=app_secret; 42 | Config.appId=app_id; 43 | Config.appPassword=app_password; 44 | sleep(1000); 45 | 46 | login(nbc); 47 | 48 | } catch (JSONException e) { 49 | logger.error(e.toString()); 50 | } catch (InterruptedException e) { 51 | e.printStackTrace(); 52 | } 53 | 54 | } 55 | } 56 | 57 | public static void login(INonBlockingConnection nbc){ 58 | JSONObject obj = new JSONObject(); 59 | try { 60 | if (Config.appId!=null && Config.appPassword!=null) { 61 | obj.put("app_id", Config.appId); 62 | obj.put("app_password", FN.MD5(Config.appPassword)); 63 | String v = FN.dataForWrite(Config.protocol_checklogin,obj); 64 | // logger.info(v); 65 | nbc.write(v); 66 | }else{ 67 | String v = FN.dataForWrite(Config.protocol_checkclient,obj); 68 | // logger.info(v); 69 | nbc.write(v); 70 | } 71 | 72 | } catch (JSONException e) { 73 | logger.error(e.toString()); 74 | } catch (ClosedChannelException e) { 75 | logger.error(e.toString()); 76 | } catch (IOException e) { 77 | logger.error(e.toString()); 78 | } 79 | 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/server/StockClientHandle.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.server; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.utils.FN; 5 | import com.dangfm.stock.socketclient.utils.ZipUtils; 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | import org.json.JSONObject; 9 | import org.slf4j.Logger; 10 | import org.slf4j.LoggerFactory; 11 | import org.xsocket.MaxReadSizeExceededException; 12 | import org.xsocket.connection.*; 13 | 14 | import java.io.IOException; 15 | import java.nio.BufferUnderflowException; 16 | import java.nio.ByteBuffer; 17 | import java.nio.channels.ClosedChannelException; 18 | import java.util.concurrent.locks.ReentrantLock; 19 | 20 | /** 21 | * socket服务器事件处理类 22 | * Created by dangfm on 17/2/2. 23 | */ 24 | public class StockClientHandle implements IDataHandler, IConnectHandler, 25 | IDisconnectHandler,IConnectionTimeoutHandler { 26 | 27 | public static final Logger logger = LoggerFactory.getLogger(StockClientHandle.class); 28 | 29 | private static ReentrantLock lock = new ReentrantLock(); 30 | 31 | /** 32 | * 连接的成功时的操作 33 | */ 34 | @Override 35 | public boolean onConnect(INonBlockingConnection nbc) throws IOException, 36 | BufferUnderflowException, MaxReadSizeExceededException { 37 | String remoteName=nbc.getRemoteAddress().getHostName(); 38 | logger.info("客户端启动成功连接行情服务器:" + Config.serverIP+":"+ Config.serverPort); 39 | // nbc.setEncoding("utf-8"); 40 | Config.isConnected = true; 41 | return true; 42 | } 43 | /** 44 | * 连接断开时的操作 45 | */ 46 | @Override 47 | public boolean onDisconnect(INonBlockingConnection nbc) throws IOException { 48 | // TODO Auto-generated method stub 49 | String remoteName=nbc.getRemoteAddress().getHostName(); 50 | logger.info("客户端断开行情服务器:" + Config.serverIP+":"+ Config.serverPort); 51 | Config.isConnected = false; 52 | return true; 53 | } 54 | 55 | @Override 56 | public boolean onConnectionTimeout(INonBlockingConnection iNonBlockingConnection) throws IOException { 57 | String remoteName=iNonBlockingConnection.getRemoteAddress().getHostName(); 58 | logger.info("客户端连接行情服务器超时:" + Config.serverIP+":"+ Config.serverPort); 59 | Config.isConnected = false; 60 | return false; 61 | } 62 | 63 | /** 64 | * 65 | * 接收到数据库时候的处理 66 | */ 67 | @Override 68 | public boolean onData(INonBlockingConnection nbc) throws IOException, 69 | BufferUnderflowException, ClosedChannelException, 70 | MaxReadSizeExceededException { 71 | 72 | // byte[] byteBuffers= nbc.readBytesByDelimiter(Config.writeEnd); 73 | String str = nbc.readStringByDelimiter(Config.writeEnd); 74 | // str = new String(str.getBytes("ISO-8859-1","utf-8")); 75 | /** 76 | * 解析数据 77 | */ 78 | StockResposeDatas.StockResposeDatas(str,nbc); 79 | str = null; 80 | // byteBuffers = null; 81 | nbc.flush(); 82 | System.gc(); 83 | return true; 84 | } 85 | 86 | 87 | 88 | } 89 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/Main.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient; 2 | import com.dangfm.stock.socketclient.market.CreateTimeLine; 3 | import com.dangfm.stock.socketclient.market.GetStockDaysLine; 4 | import com.dangfm.stock.socketclient.market.MakeMarketUpDownList; 5 | import com.dangfm.stock.socketclient.server.StockClientThread; 6 | import com.dangfm.stock.socketclient.utils.FN; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.Executors; 11 | import java.util.concurrent.ScheduledExecutorService; 12 | 13 | import static java.lang.Thread.sleep; 14 | 15 | public class Main { 16 | public static final Logger logger = LoggerFactory.getLogger(Main.class); 17 | /** 18 | * 定时任务运行池 19 | */ 20 | private static ScheduledExecutorService executor = Executors.newScheduledThreadPool(1000); 21 | 22 | public static void main(String[] args) { 23 | 24 | // 首先拿到societ服务器IP 25 | FN.getServerIp(); 26 | 27 | if(!FN.reStart()){ 28 | // windows 会检查端口是否占用,占用的就禁止启动了 29 | logger.info("****************大师兄行情客户端已经启动!!!!!******************"); 30 | try { 31 | sleep(5000); 32 | } catch (InterruptedException e) { 33 | e.printStackTrace(); 34 | } 35 | return; 36 | }else { 37 | 38 | 39 | 40 | int args0 = 0; 41 | if (args.length > 0) { 42 | String n = args[0]; 43 | args0 = Integer.parseInt(n); 44 | } 45 | // logger.info("JAVA HOME=" + Config.javaHome + ""); 46 | // logger.info("OS Name=" + Config.osName + ""); 47 | // logger.info("Me Path=" + Config.appPath + ""); 48 | // logger.info("当前最大可用内存:" + Runtime.getRuntime().maxMemory() / 1024 / 1024 + " M"); //最大可用内存,对应-Xmx 49 | 50 | // 初始化 51 | String autoStartTime = "0"; 52 | 53 | FN.createExecutor("7:00:00", 0, new StockClientThread(), true,executor); 54 | /** 55 | * 行情涨跌幅 56 | */ 57 | FN.createExecutor("9:25:00", 0, new MakeMarketUpDownList(), args0 == 1 ? true : false,executor); 58 | /** 59 | * 生成分钟线分时线 60 | */ 61 | FN.createExecutor("9:00:00", 0, new CreateTimeLine(), args0 == 1 ? true : false,executor); 62 | /** 63 | * 同步K线数据 参数2是全量更新K线,周六日默认都是全量更新的 64 | */ 65 | FN.createExecutor("20:00:00", 0, new GetStockDaysLine(args0==2), (args0 == 3 || args0==2) ? true : false,executor); 66 | 67 | if(args0==4){ 68 | /** 69 | * 只同步分钟K线数据 70 | */ 71 | FN.createExecutor("7:00:00", 0, new GetStockDaysLine(true,true), true,executor); 72 | } 73 | if(args0==5){ 74 | /** 75 | * 只同步分钟K线数据,增量同步 76 | */ 77 | FN.createExecutor("7:00:00", 0, new GetStockDaysLine(false,true), true,executor); 78 | } 79 | 80 | FN.createExecutor("7:00:00", 0, new GetStockDaysLine(false), false,executor); 81 | 82 | // 生成历史k线 83 | // createExecutor("15:10:00", 0, new CreateMinuteKline(), args0 == 2 ? true : false); 84 | } 85 | 86 | // 每天早上六点自动退出 linux定时任务会在凌晨6点30分开始启动 87 | FN.createExecutor("6:0:0", 0, new Thread() { 88 | @Override 89 | public void run() { 90 | System.out.println("程序自动退出"); 91 | System.exit(0); 92 | } 93 | }, false,executor); 94 | 95 | } 96 | 97 | 98 | 99 | 100 | } 101 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/server/StockClientThread.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.server; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.user.UserHelper; 5 | import com.dangfm.stock.socketclient.utils.FN; 6 | import com.dangfm.stock.socketclient.utils.HttpWebCollecter; 7 | import com.sun.corba.se.impl.oa.poa.POAImpl; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.xsocket.connection.INonBlockingConnection; 13 | import org.xsocket.connection.NonBlockingConnection; 14 | 15 | import java.io.IOException; 16 | import java.net.UnknownHostException; 17 | /** 18 | * Socket服务器主线程 19 | * Created by dangfm on 17/2/2. 20 | */ 21 | public class StockClientThread extends Thread{ 22 | private String PORT= Config.serverPort; 23 | private String SERVER= Config.serverIP; 24 | public static final Logger logger = LoggerFactory.getLogger(StockClientThread.class); 25 | 26 | public void run() { 27 | 28 | INonBlockingConnection nbc = startNbc(); 29 | 30 | while (true){ 31 | 32 | if (nbc==null){ 33 | // logger.info("..."); 34 | nbc = startNbc(); 35 | }else if (!nbc.isOpen()){ 36 | // logger.info("."); 37 | nbc = startNbc(); 38 | }else{ 39 | // try { 40 | // if (nbc.isOpen()) { 41 | //// nbc.write(valueForClient("check")); 42 | // } 43 | // } catch (IOException e) { 44 | // e.printStackTrace(); 45 | // } 46 | } 47 | try { 48 | if (!Config.isreConnected) { 49 | // 由于验证失败等断开链接,需要更长时间才能再次链接 50 | sleep(60*1000); 51 | }else { 52 | sleep(10000); 53 | } 54 | } catch (InterruptedException e) { 55 | e.printStackTrace(); 56 | } 57 | } 58 | 59 | } 60 | 61 | 62 | 63 | 64 | private INonBlockingConnection startNbc(){ 65 | if (SERVER.isEmpty() || SERVER==null) { 66 | return null; 67 | } 68 | 69 | try { 70 | 71 | logger.info("建立连接:"+SERVER+":"+PORT+"..."); 72 | //建立handler 73 | //采用非阻塞式的连接 74 | INonBlockingConnection nbc = new NonBlockingConnection(SERVER, Integer.parseInt(PORT), new StockClientHandle()); 75 | logger.info("成功建立连接:"+SERVER+":"+PORT); 76 | //采用阻塞式的连接 77 | //IBlockingConnection bc = new BlockingConnection("localhost", PORT); 78 | //一个非阻塞的连接是很容易就变成一个阻塞连接 79 | // IBlockingConnection bc = new BlockingConnection(nbc); 80 | //设置编码格式 81 | nbc.setEncoding("UTF-8"); 82 | // nbc.setIdleTimeoutMillis(30000); 83 | // nbc.setConnectionTimeoutMillis(10000); 84 | //设置是否自动清空缓存 85 | // nbc.setAutoflush(true); 86 | // nbc.setMaxReadBufferThreshold(2000000000); 87 | 88 | 89 | // 登录 90 | UserHelper.login(nbc); 91 | // //向客户端读取数据的信息 92 | // byte[] byteBuffers= bc.readBytesByDelimiter("|", "UTF-8"); 93 | // //打印服务器端信息 94 | // logger.info(new String(byteBuffers)); 95 | //将信息清除缓存,写入服务器端 96 | // bc.flush(); 97 | // bc.close(); 98 | return nbc; 99 | } catch (UnknownHostException e) { 100 | // TODO Auto-generated catch block 101 | logger.error(e.getMessage()); 102 | } catch (IOException e) { 103 | // TODO Auto-generated catch block 104 | // e.printStackTrace(); 105 | logger.error(e.getMessage()); 106 | } 107 | 108 | return null; 109 | 110 | 111 | } 112 | 113 | 114 | 115 | 116 | } 117 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/market/SaveKlineDatas.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.market; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.server.StockResposeDatas; 5 | import com.dangfm.stock.socketclient.utils.FN; 6 | import com.dangfm.stock.socketclient.utils.FileHelper; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.locks.ReentrantLock; 11 | 12 | /** 13 | * 保存K线数据 14 | */ 15 | public class SaveKlineDatas { 16 | public static final Logger logger = LoggerFactory.getLogger(StockResposeDatas.class); 17 | 18 | private static ReentrantLock lock = new ReentrantLock(); 19 | // 保存的路径 20 | private static String klinePath = Config.klineSavePath.isEmpty()? FN.getProjectPath():Config.klineSavePath; 21 | 22 | /** 23 | * 保存当天1分钟历史K线数据 24 | * @param code 股票代码 25 | * @param value 保存的分钟线数据 26 | * @param fuquan 复权类型 datas before after 27 | */ 28 | public static void saveMinuteKline(String code,String value,String fuquan){ 29 | String[] list = value.split("\r\n"); 30 | // logger.info("接收到当天1分钟历史数据:"+code+" = "+list.length); 31 | // 首先拿到日期 32 | if (list.length>0){ 33 | String rows = list[0]; 34 | if (!rows.isEmpty()) { 35 | if (rows.contains(",")) { 36 | String date = rows.split(",")[0]; 37 | // 生产日期文件夹 38 | String year = date.substring(0,4); 39 | String month = date.substring(4,6); 40 | String day = date.substring(6,8); 41 | String path = klinePath+"/1min/"+fuquan+"/"+year+"/"+month+day+"/"; 42 | FileHelper.makeDirs(path); 43 | String fileName = path+code.toUpperCase()+".txt"; 44 | // 保存文件 45 | FileHelper.createFile(fileName,value); 46 | logger.info("保存当天1分钟历史数据:"+code+"["+fuquan+"]"+":"+fileName); 47 | } 48 | } 49 | } 50 | } 51 | 52 | /** 53 | * 保存当天日K历史数据 54 | * @param code 股票代码 55 | * @param value 保存的k线数据 56 | * @param fuquan 复权类型 datas before after 57 | */ 58 | public static void saveDayKline(String code,String value,String fuquan){ 59 | String[] list = value.split("\r\n"); 60 | // logger.info("接收到当天日K历史数据:"+code+" = "+list.length); 61 | // 首先拿到日期 62 | if (list.length>0){ 63 | String rows = list[0]; 64 | if (!rows.isEmpty()) { 65 | if (rows.contains(",")) { 66 | String date = rows.split(",")[0]; 67 | // 生产日期文件夹 68 | String year = date.substring(0,4); 69 | String month = date.substring(4,6); 70 | String day = date.substring(6,8); 71 | String path = klinePath+"/day/"+fuquan+"/"; 72 | FileHelper.makeDirs(path); 73 | String fileName = path+code.toUpperCase()+".txt"; 74 | // 先拿出旧的文件 75 | String content = FileHelper.readToString(fileName); 76 | if (!content.isEmpty()) { 77 | // 检查是否存在当天数据 78 | String[] oldList = content.split("\r\n"); 79 | if (oldList.length>0){ 80 | String lastRow = oldList[oldList.length-1]; 81 | if (lastRow.contains(",")){ 82 | String newDate = lastRow.split(",")[0]; 83 | // 如果拿到的最新日期比之前的都大,那么就加在最后一个下面 84 | if (Integer.parseInt(date)>Integer.parseInt(newDate)){ 85 | content += value; 86 | // 保存文件 87 | FileHelper.createFile(fileName,content); 88 | // logger.info("更新保存当天日K历史数据:"+code+"["+fuquan+"]"+":"+fileName); 89 | return; 90 | } 91 | } 92 | } 93 | }else { 94 | // 保存文件 95 | FileHelper.createFile(fileName,value); 96 | // logger.info("首次保存当天日K历史数据:"+code+"["+fuquan+"]"+":"+fileName); 97 | return; 98 | } 99 | 100 | 101 | } 102 | } 103 | } 104 | 105 | logger.info("保存当天日K历史数据:"+code+"["+fuquan+"]"+"完成"); 106 | } 107 | 108 | 109 | 110 | } 111 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/market/SaveAllStocks.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.market; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.server.StockResposeDatas; 5 | import com.dangfm.stock.socketclient.utils.FN; 6 | import com.dangfm.stock.socketclient.utils.RedisCls; 7 | import org.json.JSONArray; 8 | import org.json.JSONException; 9 | import org.json.JSONObject; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.util.Set; 14 | import java.util.concurrent.locks.ReentrantLock; 15 | 16 | public class SaveAllStocks { 17 | public static final Logger logger = LoggerFactory.getLogger(SaveAllStocks.class); 18 | 19 | private static ReentrantLock lock = new ReentrantLock(); 20 | /** 21 | * 本地redis 22 | */ 23 | private static RedisCls redisCls = new RedisCls(); 24 | private static RedisCls redisSearchCls = new RedisCls(); 25 | private static RedisCls redisBlockCls = new RedisCls(); 26 | 27 | 28 | /** 29 | * 保存行业板块表到redis 30 | * @param datas 31 | */ 32 | public static void saveAllStockType_hangye(JSONArray datas){ 33 | redisBlockCls.select(Config.redisDB_upDown); 34 | redisBlockCls.setValue(Config.redisKey_Hangye_tables,datas.toString()); 35 | } 36 | 37 | /** 38 | * 保存概念板块表到redis 39 | * @param datas 40 | */ 41 | public static void saveAllStockType_gainian(JSONArray datas){ 42 | redisBlockCls.select(Config.redisDB_upDown); 43 | redisBlockCls.setValue(Config.redisKey_Gainian_tables,datas.toString()); 44 | } 45 | 46 | /** 47 | * 保存地域板块表到redis 48 | * @param datas 49 | */ 50 | public static void saveAllStockType_diqu(JSONArray datas){ 51 | redisBlockCls.select(Config.redisDB_upDown); 52 | redisBlockCls.setValue(Config.redisKey_Diqu_tables,datas.toString()); 53 | } 54 | 55 | /** 56 | * 保存股票分类表 57 | * @param key 58 | * @param value 59 | */ 60 | public static void saveAllStocks(String key,String value){ 61 | // 查询本地key 62 | if (!key.isEmpty() && !value.isEmpty()) { 63 | // logger.info("接收保存股票分类表:"+key+"="+value); 64 | // 拿到股票代码 65 | try { 66 | JSONObject obj = new JSONObject(value); 67 | if (obj!=null) { 68 | String code = obj.getString("code"); 69 | Set ss = redisCls.redis(Config.redisDB_stocks).keys(code + "*"); 70 | if (ss.size() > 0) { 71 | Object[] lists = ss.toArray(); 72 | for (int j = 0; j < lists.length; j++) { 73 | // 这样可以避免中文名称不同而重复 74 | String keys = (String) lists[j]; 75 | redisCls.redis(Config.redisDB_stocks).del(keys); 76 | // logger.info("股票数据更新:" + code + "===" + keys); 77 | } 78 | } 79 | redisCls.redis(Config.redisDB_stocks).set(key,value); 80 | // logger.debug("接收保存股票分类表:"+key); 81 | } 82 | 83 | } catch (JSONException e) { 84 | logger.error(e.toString()); 85 | } 86 | 87 | } 88 | 89 | } 90 | 91 | /** 92 | * 保存股票搜索表 93 | * @param key 94 | * @param value 95 | */ 96 | public static void saveSearchStocks(String key,String value){ 97 | // 查询本地key 98 | if (!key.isEmpty() && !value.isEmpty()) { 99 | // 拿到股票代码 100 | try { 101 | JSONObject obj = new JSONObject(value); 102 | if (obj!=null) { 103 | String code = obj.getString("code"); 104 | Set ss = redisSearchCls.redis(Config.redisDB_Search).keys(code + "*"); 105 | if (ss.size() > 0) { 106 | Object[] lists = ss.toArray(); 107 | for (int j = 0; j < lists.length; j++) { 108 | // 这样可以避免中文名称不同而重复 109 | String keys = (String) lists[j]; 110 | redisSearchCls.redis(Config.redisDB_Search).del(keys); 111 | // System.out.println("搜索key:" + code + "===" + keys); 112 | } 113 | } 114 | redisSearchCls.redis(Config.redisDB_Search).set(key,value); 115 | // logger.debug("接收保存股票搜索表:"+key); 116 | } 117 | 118 | } catch (JSONException e) { 119 | logger.error(e.toString()); 120 | } 121 | 122 | } 123 | 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/utils/FileHelper.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.utils; 2 | 3 | import java.io.*; 4 | 5 | /** 6 | * 文件操作 7 | * Created by dangfm on 17/6/10. 8 | */ 9 | public class FileHelper { 10 | /** 11 | * 创建文件 12 | * @param fileName 文件名称 13 | * @param filecontent 文件内容 14 | * @return 是否创建成功,成功则返回true 15 | */ 16 | public static boolean createFile(String fileName,String filecontent){ 17 | Boolean bool = false; 18 | File file = new File(fileName); 19 | try { 20 | //如果文件不存在,则创建新的文件 21 | if(!file.exists()){ 22 | file.createNewFile(); 23 | bool = true; 24 | System.out.println("success create file,the file is "+fileName); 25 | //创建文件成功后,写入内容到文件里 26 | writeFileContent(fileName, filecontent,true); 27 | }else{ 28 | bool = true; 29 | System.out.println("success update file,the file is "+fileName); 30 | //创建文件成功后,写入内容到文件里 31 | writeFileContent(fileName, filecontent, false); 32 | 33 | } 34 | } catch (Exception e) { 35 | e.printStackTrace(); 36 | } 37 | 38 | return bool; 39 | } 40 | 41 | /** 42 | * 向文件中写入内容 43 | * @param filepath 文件路径与名称 44 | * @param newstr 写入的内容 45 | * @return 46 | * @throws IOException 47 | */ 48 | public static boolean writeFileContent(String filepath,String newstr,boolean isNew) throws IOException { 49 | Boolean bool = false; 50 | String filein = newstr+"\r\n";//新写入的行,换行 51 | String temp = ""; 52 | 53 | FileInputStream fis = null; 54 | InputStreamReader isr = null; 55 | BufferedReader br = null; 56 | FileOutputStream fos = null; 57 | PrintWriter pw = null; 58 | try { 59 | File file = new File(filepath);//文件路径(包括文件名称) 60 | //将文件读入输入流 61 | fis = new FileInputStream(file); 62 | isr = new InputStreamReader(fis); 63 | br = new BufferedReader(isr); 64 | StringBuffer buffer = new StringBuffer(); 65 | 66 | //文件原有内容 67 | if (isNew) { 68 | for (int i = 0; (temp = br.readLine()) != null; i++) { 69 | buffer.append(temp); 70 | // 行与行之间的分隔符 相当于“\n” 71 | buffer = buffer.append(System.getProperty("line.separator")); 72 | } 73 | } 74 | buffer.append(filein); 75 | 76 | 77 | 78 | fos = new FileOutputStream(file); 79 | pw = new PrintWriter(fos); 80 | pw.write(buffer.toString().toCharArray()); 81 | pw.flush(); 82 | bool = true; 83 | } catch (Exception e) { 84 | // TODO: handle exception 85 | e.printStackTrace(); 86 | }finally { 87 | //不要忘记关闭 88 | if (pw != null) { 89 | pw.close(); 90 | } 91 | if (fos != null) { 92 | fos.close(); 93 | } 94 | if (br != null) { 95 | br.close(); 96 | } 97 | if (isr != null) { 98 | isr.close(); 99 | } 100 | if (fis != null) { 101 | fis.close(); 102 | } 103 | } 104 | return bool; 105 | } 106 | 107 | /** 108 | * 删除文件 109 | * @param fileName 文件名称 110 | * @return 111 | */ 112 | public static boolean delFile(String fileName){ 113 | Boolean bool = false; 114 | File file = new File(fileName); 115 | try { 116 | if(file.exists()){ 117 | file.delete(); 118 | bool = true; 119 | } 120 | } catch (Exception e) { 121 | // TODO: handle exception 122 | } 123 | return bool; 124 | } 125 | 126 | public static boolean makeDirs(String filePath) { 127 | if (filePath == null || filePath.isEmpty()) { 128 | return false; 129 | } 130 | 131 | File folder = new File(filePath); 132 | return (folder.exists() && folder.isDirectory()) ? true : folder.mkdirs(); 133 | } 134 | 135 | public static String readToString(String fileName) { 136 | String encoding = "UTF-8"; 137 | File file = new File(fileName); 138 | byte[] filecontent = null; 139 | if(file.exists()) { 140 | Long filelength = file.length(); 141 | filecontent = new byte[filelength.intValue()]; 142 | try { 143 | FileInputStream in = new FileInputStream(file); 144 | in.read(filecontent); 145 | in.close(); 146 | } catch (FileNotFoundException e) { 147 | e.printStackTrace(); 148 | } catch (IOException e) { 149 | e.printStackTrace(); 150 | } 151 | }else{ 152 | // System.out.println("文件不存在:" + fileName); 153 | return ""; 154 | } 155 | try { 156 | return new String(filecontent, encoding); 157 | } catch (UnsupportedEncodingException e) { 158 | System.err.println("The OS does not support " + encoding); 159 | e.printStackTrace(); 160 | return null; 161 | } 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /logs/logs_2017-03-08.log: -------------------------------------------------------------------------------- 1 | 2017-03-08 00:00:50 [ xNbcPool-1-thread-39:108356124 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 2 | 2017-03-08 00:20:28 [ xNbcPool-1-thread-40:109534292 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 3 | 2017-03-08 00:20:42 [ xNbcPool-1-thread-40:109547976 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 4 | 2017-03-08 00:40:02 [ xNbcPool-1-thread-40:110707425 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 5 | 2017-03-08 00:40:06 [ xNbcPool-1-thread-40:110711972 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 6 | 2017-03-08 00:59:56 [ xNbcPool-1-thread-41:111901776 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 7 | 2017-03-08 01:00:04 [ xNbcPool-1-thread-41:111909955 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 8 | 2017-03-08 01:09:46 [ xNbcPool-1-thread-41:112492275 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 9 | 2017-03-08 01:09:52 [ xNbcPool-1-thread-41:112498213 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 10 | 2017-03-08 01:29:11 [ xNbcPool-1-thread-41:113657089 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 11 | 2017-03-08 01:29:24 [ xNbcPool-1-thread-41:113670388 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 12 | 2017-03-08 01:39:20 [ xNbcPool-1-thread-41:114265786 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 13 | 2017-03-08 01:48:44 [ xNbcPool-1-thread-41:114829888 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 14 | 2017-03-08 02:03:49 [ xNbcPool-1-thread-42:115734987 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 15 | 2017-03-08 02:03:57 [ xNbcPool-1-thread-42:115743156 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 16 | 2017-03-08 02:14:45 [ xNbcPool-1-thread-43:116390465 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 17 | 2017-03-08 02:24:16 [ xNbcPool-1-thread-43:116961426 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 18 | 2017-03-08 02:43:55 [ xNbcPool-1-thread-44:118141284 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 19 | 2017-03-08 02:44:03 [ xNbcPool-1-thread-44:118149214 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 20 | 2017-03-08 03:03:17 [ xNbcPool-1-thread-44:119302575 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 21 | 2017-03-08 03:03:26 [ xNbcPool-1-thread-44:119311415 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 22 | 2017-03-08 03:13:35 [ xNbcPool-1-thread-44:119921097 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 23 | 2017-03-08 03:23:05 [ xNbcPool-1-thread-44:120491246 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 24 | 2017-03-08 03:42:52 [ xNbcPool-1-thread-45:121678094 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 25 | 2017-03-08 03:42:58 [ xNbcPool-1-thread-45:121683408 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 26 | 2017-03-08 03:52:39 [ xNbcPool-1-thread-45:122264971 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 27 | 2017-03-08 03:52:41 [ xNbcPool-1-thread-45:122267090 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 28 | 2017-03-08 04:02:23 [ xNbcPool-1-thread-45:122849162 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 29 | 2017-03-08 04:02:25 [ xNbcPool-1-thread-45:122851259 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 30 | 2017-03-08 04:12:24 [ xNbcPool-1-thread-45:123449487 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 31 | 2017-03-08 04:21:43 [ pool-1-thread-1:124008586 ] - [ ERROR ] Network is down 32 | 2017-03-08 04:21:53 [ xNbcPool-1-thread-45:124019058 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 33 | 2017-03-08 04:41:24 [ xNbcPool-1-thread-46:125189630 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 34 | 2017-03-08 04:41:31 [ xNbcPool-1-thread-46:125196789 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 35 | 2017-03-08 05:01:22 [ xNbcPool-1-thread-47:126388096 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 36 | 2017-03-08 05:01:28 [ pool-1-thread-1:126394126 ] - [ ERROR ] Network is down 37 | 2017-03-08 05:10:53 [ xNbcPool-1-thread-47:126958877 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 38 | 2017-03-08 05:30:20 [ xNbcPool-1-thread-47:128125635 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 39 | 2017-03-08 05:30:22 [ xNbcPool-1-thread-47:128128282 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 40 | 2017-03-08 05:50:06 [ xNbcPool-1-thread-48:129311449 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 41 | 2017-03-08 05:50:15 [ xNbcPool-1-thread-48:129320415 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 42 | 2017-03-08 06:00:03 [ xNbcPool-1-thread-48:129909389 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 43 | 2017-03-08 06:00:12 [ xNbcPool-1-thread-48:129917923 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 44 | 2017-03-08 06:09:54 [ xNbcPool-1-thread-48:130500386 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 45 | 2017-03-08 06:09:57 [ xNbcPool-1-thread-48:130502479 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 46 | 2017-03-08 06:19:38 [ xNbcPool-1-thread-48:131084305 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 47 | 2017-03-08 06:19:45 [ xNbcPool-1-thread-48:131090809 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 48 | 2017-03-08 06:39:05 [ xNbcPool-1-thread-48:132250856 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 49 | 2017-03-08 06:39:10 [ xNbcPool-1-thread-48:132256261 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 50 | 2017-03-08 06:59:02 [ xNbcPool-1-thread-49:133447791 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 51 | 2017-03-08 07:02:04 [ xNbcPool-1-thread-49:133630109 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 52 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/utils/RedisCls.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.utils; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import org.json.JSONException; 5 | import org.json.JSONObject; 6 | import org.slf4j.Logger; 7 | import org.slf4j.LoggerFactory; 8 | import redis.clients.jedis.Jedis; 9 | import redis.clients.jedis.exceptions.JedisException; 10 | 11 | import java.util.concurrent.locks.ReentrantLock; 12 | 13 | /** 14 | * Redis 15 | * Created by dangfm on 17/2/3. 16 | */ 17 | public class RedisCls { 18 | private Logger logger = LoggerFactory.getLogger(RedisCls.class); 19 | private ReentrantLock lock = new ReentrantLock(); 20 | public String redisServer = Config.redisServer; 21 | //private static String redisServer = "127.0.0.1"; 22 | public int redisPort = Config.redisPort; 23 | public String redisPassword = Config.redisPassword; 24 | private Jedis redis = null; 25 | private Jedis[] allRedis = new Jedis[100]; 26 | 27 | public RedisCls(){ 28 | init(); 29 | } 30 | 31 | public RedisCls(String server, int port, String pass){ 32 | redisServer = server; 33 | redisPassword = pass; 34 | redisPort = port; 35 | init(); 36 | } 37 | 38 | private void init(){ 39 | if (redis==null) { 40 | // 连接redis 41 | try{ 42 | redis = new Jedis(redisServer, redisPort); 43 | if (!redisPassword.isEmpty()) { 44 | // System.out.println("redis:"+redisPassword); 45 | redis.auth(redisPassword); 46 | } 47 | if (isConnect()) { 48 | // logger.info("redis:" + redisServer + ":" + redisPort + " connected!"); 49 | } 50 | }catch (Exception e){ 51 | redis.close(); 52 | redis = null; 53 | logger.error("redis:" + redisServer + ":" + redisPort + " unconnected!"); 54 | logger.error(e.toString()); 55 | } 56 | 57 | } 58 | } 59 | 60 | private void restart(){ 61 | 62 | } 63 | 64 | public Boolean isConnect(){ 65 | if (redis!=null){ 66 | return true; 67 | } 68 | String connect_status=""; 69 | try { 70 | connect_status = redis.ping(); 71 | if (connect_status.equals("PONG")) { 72 | return true; 73 | } 74 | }catch (Exception e){ 75 | logger.error("redis:" + redisServer + ":" + redisPort + " ping = "+connect_status); 76 | logger.error(e.toString()); 77 | } 78 | // 如果redis无法连接,启动重连 79 | 80 | return false; 81 | } 82 | 83 | public void disconnect(){ 84 | if (redis!=null) 85 | redis.disconnect(); 86 | } 87 | 88 | public void destroy(){ 89 | // 销毁 90 | logger.info("销毁redis:" + redisServer + ":" + redisPort); 91 | if (redis!=null){ 92 | redis.disconnect(); 93 | redis.close(); 94 | redis = null; 95 | } 96 | } 97 | 98 | 99 | public Jedis getRedis() { 100 | return redis; 101 | } 102 | 103 | public Jedis redis(int databaseNumber){ 104 | try { 105 | if (isConnect()) { 106 | lock.lock(); 107 | redis.select(databaseNumber); 108 | lock.unlock(); 109 | } 110 | }catch (JedisException e){ 111 | lock.unlock(); 112 | logger.error(e.toString()); 113 | } 114 | return redis; 115 | } 116 | 117 | public void setValue(String key, String value) { 118 | 119 | 120 | try { 121 | if (isConnect()) { 122 | lock.lock(); 123 | if (value != null) { 124 | String r = redis.set(key, value); 125 | } 126 | // System.out.println(r); 127 | lock.unlock(); 128 | } 129 | }catch (JedisException e){ 130 | lock.unlock(); 131 | logger.error(e.toString()); 132 | } 133 | 134 | //redis.lpush(key,value); 135 | //redis.set(key, value); 136 | } 137 | 138 | public String getValue(Object key) { 139 | String value = null; 140 | try { 141 | 142 | if (isConnect()) { 143 | lock.lock(); 144 | value = redis.get((String) key); 145 | lock.unlock(); 146 | } 147 | }catch (JedisException e){ 148 | lock.unlock(); 149 | logger.error(e.toString()); 150 | } 151 | 152 | // try{ 153 | // 154 | // }catch (Exception e){ 155 | // System.out.println("出错了"); 156 | // lock.unlock(); 157 | // } 158 | // finally { 159 | // lock.unlock(); 160 | // } 161 | 162 | 163 | return value; 164 | } 165 | 166 | /** 167 | * 获取某个股票的实时行情对象 168 | * @param code 169 | * @return 170 | */ 171 | public JSONObject getStockPrices(String code){ 172 | JSONObject obj=null; 173 | String json = getValue(code); 174 | if (json!=null){ 175 | try { 176 | obj = new JSONObject(json); 177 | 178 | } catch (JSONException e) { 179 | logger.error(e.toString()); 180 | } 181 | } 182 | 183 | return obj; 184 | } 185 | 186 | /** 187 | * 切换数据库 188 | * 189 | * @param num 190 | */ 191 | public void select(int num) { 192 | if (isConnect()) { 193 | lock.lock(); 194 | String value = null; 195 | redis.select(num); 196 | lock.unlock(); 197 | } 198 | } 199 | } -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/utils/ZipUtils.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.utils; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | 6 | import java.io.ByteArrayInputStream; 7 | import java.io.ByteArrayOutputStream; 8 | import java.io.IOException; 9 | import java.util.zip.*; 10 | 11 | public class ZipUtils { 12 | public static final Logger logger = LoggerFactory.getLogger(ZipUtils.class); 13 | /** 14 | 15 | * 使用gzip进行压缩 16 | */ 17 | public static String gzip(String primStr) { 18 | if (primStr == null || primStr.length() == 0) { 19 | return primStr; 20 | } 21 | 22 | ByteArrayOutputStream out = new ByteArrayOutputStream(); 23 | 24 | GZIPOutputStream gzip=null; 25 | try { 26 | gzip = new GZIPOutputStream(out); 27 | gzip.write(primStr.getBytes()); 28 | } catch (IOException e) { 29 | e.printStackTrace(); 30 | }finally{ 31 | if(gzip!=null){ 32 | try { 33 | gzip.close(); 34 | } catch (IOException e) { 35 | e.printStackTrace(); 36 | } 37 | } 38 | } 39 | 40 | 41 | return new sun.misc.BASE64Encoder().encode(out.toByteArray()); 42 | } 43 | 44 | /** 45 | * 46 | *

Description:使用gzip进行解压缩

47 | * @param compressedStr 48 | * @return 49 | */ 50 | public static String gunzip(String compressedStr){ 51 | if(compressedStr==null){ 52 | return null; 53 | } 54 | 55 | ByteArrayOutputStream out= new ByteArrayOutputStream(); 56 | ByteArrayInputStream in=null; 57 | GZIPInputStream ginzip=null; 58 | byte[] compressed=null; 59 | String decompressed = null; 60 | try { 61 | compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr); 62 | in=new ByteArrayInputStream(compressed); 63 | ginzip=new GZIPInputStream(in); 64 | 65 | byte[] buffer = new byte[1024]; 66 | int offset = -1; 67 | while ((offset = ginzip.read(buffer)) != -1) { 68 | out.write(buffer, 0, offset); 69 | } 70 | decompressed=out.toString(); 71 | } catch (IOException e) { 72 | e.printStackTrace(); 73 | } finally { 74 | if (ginzip != null) { 75 | try { 76 | ginzip.close(); 77 | } catch (IOException e) { 78 | } 79 | } 80 | if (in != null) { 81 | try { 82 | in.close(); 83 | } catch (IOException e) { 84 | } 85 | } 86 | if (out != null) { 87 | try { 88 | out.close(); 89 | } catch (IOException e) { 90 | } 91 | } 92 | } 93 | 94 | return decompressed; 95 | } 96 | 97 | /** 98 | * 使用zip进行压缩 99 | * @param str 压缩前的文本 100 | * @return 返回压缩后的文本 101 | */ 102 | public static final String zip(String str) { 103 | if (str == null) 104 | return null; 105 | byte[] compressed; 106 | ByteArrayOutputStream out = null; 107 | ZipOutputStream zout = null; 108 | String compressedStr = null; 109 | try { 110 | out = new ByteArrayOutputStream(); 111 | zout = new ZipOutputStream(out); 112 | zout.putNextEntry(new ZipEntry("0")); 113 | zout.write(str.getBytes()); 114 | zout.closeEntry(); 115 | compressed = out.toByteArray(); 116 | compressedStr = new sun.misc.BASE64Encoder().encodeBuffer(compressed); 117 | } catch (IOException e) { 118 | compressed = null; 119 | } finally { 120 | if (zout != null) { 121 | try { 122 | zout.close(); 123 | } catch (IOException e) { 124 | } 125 | } 126 | if (out != null) { 127 | try { 128 | out.close(); 129 | } catch (IOException e) { 130 | } 131 | } 132 | } 133 | return compressedStr; 134 | } 135 | 136 | /** 137 | * 使用zip进行解压缩 138 | * @param compressedStr 压缩后的文本 139 | * @return 解压后的字符串 140 | */ 141 | public static final String unzip(String compressedStr) { 142 | if (compressedStr == null) { 143 | return null; 144 | } 145 | 146 | ByteArrayOutputStream out = null; 147 | ByteArrayInputStream in = null; 148 | ZipInputStream zin = null; 149 | String decompressed = null; 150 | try { 151 | byte[] compressed = new sun.misc.BASE64Decoder().decodeBuffer(compressedStr); 152 | out = new ByteArrayOutputStream(); 153 | in = new ByteArrayInputStream(compressed); 154 | zin = new ZipInputStream(in); 155 | zin.getNextEntry(); 156 | byte[] buffer = new byte[1024]; 157 | int offset = -1; 158 | while ((offset = zin.read(buffer)) != -1) { 159 | out.write(buffer, 0, offset); 160 | } 161 | decompressed = out.toString(); 162 | } catch (IOException e) { 163 | 164 | decompressed = null; 165 | } finally { 166 | if (zin != null) { 167 | try { 168 | zin.close(); 169 | } catch (IOException e) { 170 | } 171 | } 172 | if (in != null) { 173 | try { 174 | in.close(); 175 | } catch (IOException e) { 176 | } 177 | } 178 | if (out != null) { 179 | try { 180 | out.close(); 181 | } catch (IOException e) { 182 | } 183 | } 184 | } 185 | return decompressed; 186 | } 187 | } -------------------------------------------------------------------------------- /logs/error_2017-10-22.log: -------------------------------------------------------------------------------- 1 | 2017-10-22 08:55:49 [ main:194 ] - [ ERROR ] redis 127.0.0.1:6379 disconnected 2 | 2017-10-22 08:55:49 [ main:200 ] - [ ERROR ] redis 127.0.0.1:6379 disconnected 3 | 2017-10-22 09:04:04 [ pool-1-thread-490:495098 ] - [ ERROR ] [7658c33915f41942e2c74909ca6C3f4] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=OP_READ (1) isValid=true, isOpen=true, lastException=null) 4 | 2017-10-22 09:04:04 [ pool-1-thread-364:494820 ] - [ ERROR ] [7658c33915f41942e2c74909ca6C3f2] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=OP_READ (1) isValid=true, isOpen=true, lastException=null) 5 | 2017-10-22 12:54:29 [ pool-1-thread-468:14319629 ] - [ ERROR ] [7658c33915f41942e2c74909ca6Cf85] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=OP_WRITE, OP_READ (5) isValid=true, isOpen=true, lastException=null) 6 | 2017-10-22 12:54:29 [ pool-1-thread-791:14319629 ] - [ ERROR ] [7658c33915f41942e2c74909ca6Cf83] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=OP_WRITE, OP_READ (5) isValid=true, isOpen=true, lastException=null) 7 | 2017-10-22 17:36:08 [ pool-1-thread-262:31218985 ] - [ ERROR ] Operation timed out 8 | 2017-10-22 16:48:48 [ pool-1-thread-35:28379013 ] - [ ERROR ] [7658c33915f41942e2c74909ca6C1388] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=OP_READ (1) isValid=true, isOpen=true, lastException=null) 9 | 2017-10-22 18:14:26 [ pool-1-thread-657:33516225 ] - [ ERROR ] [7658c33915f41942e2c74909ca6C1507] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=, isOpen=false, lastException=java.io.IOException: Error by set write selection key now java.io.IOException: [7658c33915f41942e2c74909ca6C1507] Error occured by setting write selection key. key is null 10 | at org.xsocket.connection.IoSocketDispatcher.setWriteSelectionKeyNow(IoSocketDispatcher.java:582) 11 | at org.xsocket.connection.IoSocketHandler$SetWriteSelectionKeyTask.run(IoSocketHandler.java:424) 12 | at org.xsocket.connection.IoSocketDispatcher.performKeyUpdateTasks(IoSocketDispatcher.java:537) 13 | at org.xsocket.connection.IoSocketDispatcher.run(IoSocketDispatcher.java:227) 14 | at java.lang.Thread.run(Thread.java:748) 15 | ) 16 | 2017-10-22 18:23:20 [ pool-1-thread-857:34050661 ] - [ ERROR ] Connection reset by peer 17 | 2017-10-22 17:36:31 [ pool-1-thread-756:31241717 ] - [ ERROR ] Operation timed out 18 | 2017-10-22 17:36:31 [ pool-1-thread-606:31241706 ] - [ ERROR ] Operation timed out 19 | 2017-10-22 17:35:56 [ pool-1-thread-20:31206531 ] - [ ERROR ] Operation timed out 20 | 2017-10-22 17:35:51 [ pool-1-thread-869:31201769 ] - [ ERROR ] Operation timed out 21 | 2017-10-22 17:35:48 [ pool-1-thread-712:31198385 ] - [ ERROR ] Operation timed out 22 | 2017-10-22 17:35:14 [ pool-1-thread-489:31165188 ] - [ ERROR ] Operation timed out 23 | 2017-10-22 17:35:14 [ pool-1-thread-2:31164880 ] - [ ERROR ] Operation timed out 24 | 2017-10-22 17:35:14 [ pool-1-thread-774:31164880 ] - [ ERROR ] Operation timed out 25 | 2017-10-22 17:35:03 [ pool-1-thread-371:31153727 ] - [ ERROR ] Operation timed out 26 | 2017-10-22 17:34:32 [ pool-1-thread-422:31122320 ] - [ ERROR ] Operation timed out 27 | 2017-10-22 17:34:20 [ pool-1-thread-87:31110920 ] - [ ERROR ] Operation timed out 28 | 2017-10-22 17:33:44 [ pool-1-thread-416:31074942 ] - [ ERROR ] Operation timed out 29 | 2017-10-22 17:33:44 [ pool-1-thread-323:31074942 ] - [ ERROR ] Operation timed out 30 | 2017-10-22 17:33:42 [ pool-1-thread-469:31072631 ] - [ ERROR ] Operation timed out 31 | 2017-10-22 17:31:57 [ pool-1-thread-493:30967795 ] - [ ERROR ] Network is unreachable 32 | 2017-10-22 17:31:26 [ pool-1-thread-850:30936350 ] - [ ERROR ] Network is unreachable 33 | 2017-10-22 17:30:11 [ pool-1-thread-310:30861326 ] - [ ERROR ] Network is unreachable 34 | 2017-10-22 17:30:11 [ pool-1-thread-46:30861326 ] - [ ERROR ] Network is unreachable 35 | 2017-10-22 17:29:58 [ pool-1-thread-586:30849203 ] - [ ERROR ] Network is unreachable 36 | 2017-10-22 17:29:58 [ pool-1-thread-196:30849200 ] - [ ERROR ] Network is unreachable 37 | 2017-10-22 17:29:58 [ pool-1-thread-736:30848927 ] - [ ERROR ] Network is unreachable 38 | 2017-10-22 17:29:45 [ pool-1-thread-211:30835602 ] - [ ERROR ] Network is unreachable 39 | 2017-10-22 17:29:11 [ pool-1-thread-848:30801930 ] - [ ERROR ] Network is unreachable 40 | 2017-10-22 17:29:07 [ pool-1-thread-116:30797942 ] - [ ERROR ] Network is unreachable 41 | 2017-10-22 17:27:09 [ pool-1-thread-628:30680065 ] - [ ERROR ] Network is unreachable 42 | 2017-10-22 17:25:49 [ pool-1-thread-784:30599925 ] - [ ERROR ] Network is unreachable 43 | 2017-10-22 17:25:45 [ pool-1-thread-23:30595577 ] - [ ERROR ] Network is unreachable 44 | 2017-10-22 17:25:40 [ pool-1-thread-805:30590232 ] - [ ERROR ] Network is unreachable 45 | 2017-10-22 17:21:06 [ pool-1-thread-429:30316986 ] - [ ERROR ] [7658c33915f41942e2c74909ca6C144a] send timeout 1 min reached. returning from sync flushing (countIsWritten=0, countOnException=0, sendBytes=0, receivedBytes=0, sendQueueSize=72, countUnknownOnWritten=0, sendQueueSize=72, countIncompleteWrites= sendBytes=0, reveivedBytes=0, key=OP_READ (1) isValid=true, isOpen=true, lastException=null) 46 | 2017-10-22 17:21:04 [ pool-1-thread-544:30315013 ] - [ ERROR ] Connection reset by peer 47 | 2017-10-22 18:33:25 [ pool-1-thread-41:34655354 ] - [ ERROR ] Connection reset by peer 48 | 2017-10-22 18:33:25 [ pool-1-thread-881:34655354 ] - [ ERROR ] Connection reset by peer 49 | 2017-10-22 18:33:25 [ pool-1-thread-807:34655353 ] - [ ERROR ] Connection reset by peer 50 | 2017-10-22 18:33:25 [ pool-1-thread-143:34655353 ] - [ ERROR ] Connection reset by peer 51 | 2017-10-22 18:33:25 [ pool-1-thread-186:34655350 ] - [ ERROR ] Connection reset by peer 52 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/Config.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient; 2 | 3 | import com.dangfm.stock.socketclient.utils.FN; 4 | import org.json.JSONArray; 5 | import org.json.JSONObject; 6 | 7 | /** 8 | * 配置类 9 | * Created by dangfm on 16/3/19. 10 | */ 11 | public class Config { 12 | // 配置文件名 13 | public static final String configFileName = "config.properties"; // 本地测试 14 | // public static final String configFileName = "ForlightClientConfig.properties"; // 为明服务器 15 | 16 | // 本地 redis 服务器 17 | public static final String redisServer = FN.getProperty("redisServer"); 18 | public static final int redisPort = Integer.parseInt(FN.getProperty("redisPort")); 19 | public static final String redisPassword = FN.getProperty("redisPassword"); 20 | 21 | // 服务端口号 22 | public static String serverPort = ""; 23 | public static String serverIP = ""; 24 | 25 | // 开发者信息 26 | public static String appKey = FN.getProperty("appKey"); 27 | public static String appSecret = FN.getProperty("appSecret"); 28 | // 登陆信息 29 | public static String appId = FN.getProperty("appId"); 30 | public static String appPassword = FN.getProperty("appPassword"); 31 | 32 | // 服务器IP地址 33 | public static String socketServer = FN.getProperty("socketServer"); 34 | public static String socketServer_kline = "/kline.php"; 35 | public static String socketServer_Ip = "/socketserverip.php"; 36 | public static String klineServer_Ip = "/klineserverip.php"; 37 | 38 | // k线缓存地址 39 | public static final String klineSavePath = FN.getProperty("klineSavePath"); 40 | /** 41 | * 是否采集历史日K数据 42 | */ 43 | public static final boolean isCollectionHistoryKline = Boolean.parseBoolean(FN.getProperty("isCollectionHistoryKline")); 44 | /** 45 | * 是否采集历史分钟线数据 46 | */ 47 | public static final boolean isCollectionHistoryMinKline = Boolean.parseBoolean(FN.getProperty("isCollectionHistoryMinKline")); 48 | /** 49 | * 是否采集历史分钟线复权数据 50 | */ 51 | public static final boolean isCollectionHistoryMinKline_fq = Boolean.parseBoolean(FN.getProperty("isCollectionHistoryMinKline_fq")); 52 | 53 | // JAVA 安装路径 54 | public static final String javaHome = System.getProperty("java.home"); 55 | public static final String osName = System.getProperty("os.name"); 56 | public static final String appPath = FN.getProjectPath(); 57 | 58 | 59 | // 行业,概念,地域涨跌幅 60 | // 行业涨幅redis缓存key 61 | public static String redisKey_Hangye = "Hangye_UpListKey"; 62 | // 概念涨幅redis缓存key 63 | public static String redisKey_Gainian = "Gainian_UpListKey"; 64 | // 地区涨幅redis缓存key 65 | public static String redisKey_Diqu = "Diqu_UpListKey"; 66 | // 行业表 67 | public static String redisKey_Hangye_tables = "Hangye_Tables"; 68 | // 概念表 69 | public static String redisKey_Gainian_tables = "Gainian_Tables"; 70 | // 地区表 71 | public static String redisKey_Diqu_tables = "Diqu_Tables"; 72 | // 个股涨跌幅缓存key 73 | public static String redisKey_Stock_UpdownList = "Stock_UpdownList"; 74 | // 除权列表key 75 | public static String redisKey_exright_tables = "ExRight_Tables"; 76 | // 财务列表key 77 | public static String redisKey_financial_tables = "Financial_Tables"; 78 | 79 | // 保存推送过来的实时每笔动态数据 80 | public static JSONObject realtimeStockDatas = new JSONObject(); 81 | 82 | 83 | 84 | public static int redisDB_market = 0; // 实时行情 85 | public static int redisDB_kLineData = 1; // k线原始数据专用 86 | public static int redisDB_Search = 2; // 搜索专用 87 | public static int redisDB_simulationBuy = 3; // 模拟交易买入队列 88 | public static int getRedisDB_simulationSell = 4;// 模拟交易卖出队列 89 | public static int getRedisDB_simulationAccount = 5;// 模拟交易账户队列 90 | public static int redisDB_kLineHoufuquan = 7; // k线后复权专用 91 | public static int redisDB_kLineQianfuquan = 6; // k线前复权专用 92 | public static int redisDB_upDown = 8; // 涨跌幅 93 | public static int redisDB_stocks = 9; // 保存股票数据 94 | public static int redisDB_marketzip = 10; // 压缩过的实时行情数据 95 | public static int redisDB_cache = 11; // 接口核心库缓存的区域 96 | public static int redisDB_minKlineData = 12; // 当日分钟线数据 97 | public static int redisDB_otherWode = 15; // 存储涨幅大于9%跌幅小于-%9的股票, key=sh000006 value=10(每天减1,0的时候删除) 98 | public static int redisDB_socketServerReceiveDB = 11; // socket服务用来存储客户端发送过来的最后请求数据 99 | 100 | public static String smtp_emal = "stocksync@163.com"; 101 | public static String smtp_pass = "dong261811252"; 102 | public static String smtp_server = "smtp.163.com"; 103 | public static int smtp_port = 25; 104 | public static String adminEmail = "dangfm@qq.com"; 105 | 106 | 107 | 108 | // 是否断开继续连接 109 | public static boolean isreConnected = true; 110 | // 是否连接上 111 | public static boolean isConnected = false; 112 | 113 | // 请求不能为空 114 | public static final int error_request_noempty = 100001; 115 | // 请求不合法 116 | public static final int error_request_noauthorized = 100002; 117 | // 请求未包含任何合法参数 118 | public static final int error_request_noparams = 100003; 119 | // 访问的IP("+nbcIp+")不合法,请添加IP白名单 120 | public static final int error_request_ipauthorized = 100004; 121 | // 客户端合法验证失败 122 | public static final int error_client_noauthorized = 100005; 123 | // 客户端过期了,需要续费 124 | public static final int error_client_expired = 100006; 125 | // 服务器错误 126 | public static final int error_serviceerror = 100007; 127 | // 用户名密码不能为空 128 | public static final int error_user_empty = 100008; 129 | // 请求不能为空 130 | public static final int error_user_noauthorized = 100009; 131 | 132 | 133 | // 发送数据的换行符 134 | public static final String writeEnd = "######\r\n######"; 135 | // 协议 136 | // 注册 137 | public static String protocol_register = "protocol_register"; 138 | // 合法性验证协议 139 | public static String protocol_checkclient = "protocol_checkclient"; 140 | // 登陆协议 141 | public static String protocol_checklogin = "protocol_checklogin"; 142 | // 心跳 143 | public static String protocol_heart = "protocol_heart"; 144 | // 发送实时行情的key键名数据 145 | public static String protocol_json_names = "protocol_json_names"; 146 | // 发送实时行情数据 147 | public static String protocol_realtime = "protocol_realtime"; 148 | // 发送当天日K数据 149 | public static String protocol_todayKline = "protocol_todayKline"; 150 | // 发送当天日K数据 前复权 151 | public static String protocol_todayKline_before = "protocol_todayKline_before"; 152 | // 发送当天日K数据 后复权 153 | public static String protocol_todayKline_after = "protocol_todayKline_after"; 154 | // 发送当天日1分钟数据 155 | public static String protocol_today1MinuteKline = "protocol_today1MinuteKline"; 156 | // 发送当天日1分钟数据 前复权 157 | public static String protocol_today1MinuteKline_before = "protocol_today1MinuteKline_before"; 158 | // 发送当天日1分钟数据 后复权 159 | public static String protocol_today1MinuteKline_after = "protocol_today1MinuteKline_after"; 160 | // 发送当天日5分钟数据 161 | public static String protocol_today5MinuteKline = "protocol_today5MinuteKline"; 162 | // 发送当天日5分钟数据 前复权 163 | public static String protocol_today5MinuteKline_before = "protocol_today5MinuteKline_before"; 164 | // 发送当天日5分钟数据 后复权 165 | public static String protocol_today5MinuteKline_after = "protocol_today5MinuteKline_after"; 166 | // 发送股票分类表 167 | public static String protocol_allstocks = "protocol_allstocks"; 168 | // 发送股票搜索表 169 | public static String protocol_searchstocks = "protocol_searchstocks"; 170 | // 发送股票行业分类表 171 | public static String protocol_hangye_tables = "protocol_hangye_tables"; 172 | // 发送股票概念分类表 173 | public static String protocol_gainian_tables = "protocol_gainian_tables"; 174 | // 发送股票地区分类表 175 | public static String protocol_diqu_tables = "protocol_diqu_tables"; 176 | } 177 | -------------------------------------------------------------------------------- /logs/logs_2017-03-06.log: -------------------------------------------------------------------------------- 1 | 2017-03-06 17:26:23 [ main:0 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 2 | 2017-03-06 17:26:23 [ main:2 ] - [ INFO ] OS Name=Mac OS X 3 | 2017-03-06 17:26:23 [ main:3 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 4 | 2017-03-06 17:26:23 [ main:3 ] - [ INFO ] 当前最大可用内存:1820 M 5 | 2017-03-06 17:26:23 [ main:120 ] - [ INFO ] redis 127.0.0.1:6379 connected! 6 | 2017-03-06 17:26:23 [ main:126 ] - [ INFO ] redis 127.0.0.1:6379 connected! 7 | 2017-03-06 17:26:24 [ pool-1-thread-2:1386 ] - [ INFO ] 生成5分钟k线的日期已经是最新的,无需生成 8 | 2017-03-06 17:26:24 [ pool-1-thread-2:1394 ] - [ INFO ] 生成15分钟k线的日期已经是最新的,无需生成 9 | 2017-03-06 17:26:24 [ pool-1-thread-2:1401 ] - [ INFO ] 生成30分钟k线的日期已经是最新的,无需生成 10 | 2017-03-06 17:26:24 [ pool-1-thread-2:1404 ] - [ INFO ] 生成60分钟k线的日期已经是最新的,无需生成 11 | 2017-03-06 17:26:24 [ xNbcPool-1-thread-1:1520 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 12 | 2017-03-06 17:26:24 [ pool-1-thread-1:1550 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 13 | 2017-03-06 17:27:28 [ main:1 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 14 | 2017-03-06 17:27:28 [ main:1 ] - [ INFO ] OS Name=Mac OS X 15 | 2017-03-06 17:27:28 [ main:1 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 16 | 2017-03-06 17:27:28 [ main:2 ] - [ INFO ] 当前最大可用内存:1820 M 17 | 2017-03-06 17:27:29 [ main:103 ] - [ INFO ] redis 127.0.0.1:6379 connected! 18 | 2017-03-06 17:27:29 [ main:103 ] - [ INFO ] redis 127.0.0.1:6379 connected! 19 | 2017-03-06 17:27:30 [ pool-1-thread-2:1512 ] - [ INFO ] 生成5分钟k线成功 20 | 2017-03-06 17:27:30 [ xNbcPool-1-thread-1:1544 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 21 | 2017-03-06 17:27:30 [ pool-1-thread-1:1584 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 22 | 2017-03-06 17:27:30 [ pool-1-thread-2:1609 ] - [ INFO ] 生成15分钟k线成功 23 | 2017-03-06 17:27:30 [ pool-1-thread-2:1615 ] - [ INFO ] 生成30分钟k线成功 24 | 2017-03-06 17:27:30 [ pool-1-thread-2:1618 ] - [ INFO ] 生成60分钟k线成功 25 | 2017-03-06 17:28:34 [ main:0 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 26 | 2017-03-06 17:28:34 [ main:3 ] - [ INFO ] OS Name=Mac OS X 27 | 2017-03-06 17:28:34 [ main:4 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 28 | 2017-03-06 17:28:34 [ main:5 ] - [ INFO ] 当前最大可用内存:1820 M 29 | 2017-03-06 17:28:35 [ main:228 ] - [ INFO ] redis 127.0.0.1:6379 connected! 30 | 2017-03-06 17:28:35 [ main:230 ] - [ INFO ] redis 127.0.0.1:6379 connected! 31 | 2017-03-06 17:28:36 [ xNbcPool-1-thread-1:1694 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 32 | 2017-03-06 17:28:36 [ pool-1-thread-1:1720 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 33 | 2017-03-06 17:28:36 [ pool-1-thread-2:1750 ] - [ INFO ] 生成5分钟k线的日期已经是最新的,无需生成 34 | 2017-03-06 17:28:36 [ pool-1-thread-2:1768 ] - [ INFO ] 生成15分钟k线的日期已经是最新的,无需生成 35 | 2017-03-06 17:28:36 [ pool-1-thread-2:1781 ] - [ INFO ] 生成30分钟k线的日期已经是最新的,无需生成 36 | 2017-03-06 17:28:36 [ pool-1-thread-2:1789 ] - [ INFO ] 生成60分钟k线的日期已经是最新的,无需生成 37 | 2017-03-06 17:29:21 [ main:1 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 38 | 2017-03-06 17:29:21 [ main:3 ] - [ INFO ] OS Name=Mac OS X 39 | 2017-03-06 17:29:21 [ main:3 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 40 | 2017-03-06 17:29:21 [ main:3 ] - [ INFO ] 当前最大可用内存:1820 M 41 | 2017-03-06 17:29:21 [ main:100 ] - [ INFO ] redis 127.0.0.1:6379 connected! 42 | 2017-03-06 17:29:21 [ main:107 ] - [ INFO ] redis 127.0.0.1:6379 connected! 43 | 2017-03-06 17:29:23 [ pool-1-thread-1:1487 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 44 | 2017-03-06 17:29:23 [ pool-1-thread-2:1496 ] - [ DEBUG ] 生成5分钟k线的日期已经是最新的,无需生成 45 | 2017-03-06 17:29:23 [ pool-1-thread-2:1534 ] - [ DEBUG ] 生成15分钟k线的日期已经是最新的,无需生成 46 | 2017-03-06 17:29:23 [ pool-1-thread-2:1544 ] - [ DEBUG ] 生成30分钟k线的日期已经是最新的,无需生成 47 | 2017-03-06 17:29:23 [ pool-1-thread-2:1548 ] - [ DEBUG ] 生成60分钟k线的日期已经是最新的,无需生成 48 | 2017-03-06 17:29:24 [ xNbcPool-1-thread-1:2260 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 49 | 2017-03-06 17:30:05 [ main:1 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 50 | 2017-03-06 17:30:05 [ main:3 ] - [ INFO ] OS Name=Mac OS X 51 | 2017-03-06 17:30:05 [ main:3 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 52 | 2017-03-06 17:30:05 [ main:4 ] - [ INFO ] 当前最大可用内存:1820 M 53 | 2017-03-06 17:30:05 [ main:178 ] - [ INFO ] redis 127.0.0.1:6379 connected! 54 | 2017-03-06 17:30:05 [ main:186 ] - [ INFO ] redis 127.0.0.1:6379 connected! 55 | 2017-03-06 17:30:11 [ pool-1-thread-2:6174 ] - [ DEBUG ] 生成5分钟k线的日期已经是最新的,无需生成 56 | 2017-03-06 17:30:11 [ pool-1-thread-2:6179 ] - [ DEBUG ] 生成15分钟k线的日期已经是最新的,无需生成 57 | 2017-03-06 17:30:11 [ pool-1-thread-2:6184 ] - [ DEBUG ] 生成30分钟k线的日期已经是最新的,无需生成 58 | 2017-03-06 17:30:11 [ pool-1-thread-2:6185 ] - [ DEBUG ] 生成60分钟k线的日期已经是最新的,无需生成 59 | 2017-03-06 17:30:11 [ xNbcPool-1-thread-1:6325 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 60 | 2017-03-06 17:30:11 [ pool-1-thread-1:6370 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 61 | 2017-03-06 17:30:44 [ main:1 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 62 | 2017-03-06 17:30:44 [ main:9 ] - [ INFO ] OS Name=Mac OS X 63 | 2017-03-06 17:30:44 [ main:10 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 64 | 2017-03-06 17:30:44 [ main:27 ] - [ INFO ] 当前最大可用内存:1820 M 65 | 2017-03-06 17:30:44 [ main:275 ] - [ ERROR ] redis 127.0.0.1:6379 disconnected 66 | 2017-03-06 17:30:44 [ main:277 ] - [ ERROR ] redis 127.0.0.1:6379 disconnected 67 | 2017-03-06 17:30:45 [ xNbcPool-1-thread-1:1725 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 68 | 2017-03-06 17:30:45 [ pool-1-thread-1:1766 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 69 | 2017-03-06 17:30:46 [ pool-1-thread-2:1847 ] - [ DEBUG ] 生成5分钟k线的日期已经是最新的,无需生成 70 | 2017-03-06 17:30:46 [ pool-1-thread-2:1866 ] - [ DEBUG ] 生成15分钟k线的日期已经是最新的,无需生成 71 | 2017-03-06 17:30:46 [ pool-1-thread-2:1876 ] - [ DEBUG ] 生成30分钟k线的日期已经是最新的,无需生成 72 | 2017-03-06 17:30:46 [ pool-1-thread-2:1883 ] - [ DEBUG ] 生成60分钟k线的日期已经是最新的,无需生成 73 | 2017-03-06 17:31:53 [ main:0 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 74 | 2017-03-06 17:31:53 [ main:3 ] - [ INFO ] OS Name=Mac OS X 75 | 2017-03-06 17:31:53 [ main:3 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 76 | 2017-03-06 17:31:53 [ main:4 ] - [ INFO ] 当前最大可用内存:1820 M 77 | 2017-03-06 17:31:54 [ main:193 ] - [ INFO ] redis 127.0.0.1:6379 connected! 78 | 2017-03-06 17:31:54 [ main:195 ] - [ INFO ] redis 127.0.0.1:6379 connected! 79 | 2017-03-06 17:31:55 [ xNbcPool-1-thread-1:1655 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 80 | 2017-03-06 17:31:55 [ pool-1-thread-2:1674 ] - [ DEBUG ] 生成5分钟k线的日期已经是最新的,无需生成 81 | 2017-03-06 17:31:55 [ pool-1-thread-1:1678 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 82 | 2017-03-06 17:31:55 [ pool-1-thread-2:1690 ] - [ DEBUG ] 生成15分钟k线的日期已经是最新的,无需生成 83 | 2017-03-06 17:31:55 [ pool-1-thread-2:1700 ] - [ DEBUG ] 生成30分钟k线的日期已经是最新的,无需生成 84 | 2017-03-06 17:31:55 [ pool-1-thread-2:1709 ] - [ DEBUG ] 生成60分钟k线的日期已经是最新的,无需生成 85 | 2017-03-06 17:54:54 [ main:0 ] - [ INFO ] JAVA HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_73.jdk/Contents/Home/jre 86 | 2017-03-06 17:54:54 [ main:1 ] - [ INFO ] OS Name=Mac OS X 87 | 2017-03-06 17:54:54 [ main:1 ] - [ INFO ] Me Path=/Users/dangfm/Documents/workspace/stocksocketclient/out/production/stocksocketclient 88 | 2017-03-06 17:54:54 [ main:1 ] - [ INFO ] 当前最大可用内存:1820 M 89 | 2017-03-06 17:54:54 [ main:45 ] - [ INFO ] redis 127.0.0.1:6379 connected! 90 | 2017-03-06 17:54:54 [ main:46 ] - [ INFO ] redis 127.0.0.1:6379 connected! 91 | 2017-03-06 17:54:56 [ pool-1-thread-1:1451 ] - [ INFO ] The Socket Client start on port: 9099 IP:101.37.23.52 92 | 2017-03-06 17:54:56 [ xNbcPool-1-thread-1:2096 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 93 | -------------------------------------------------------------------------------- /logs/logs_2017-03-07.log: -------------------------------------------------------------------------------- 1 | 2017-03-07 02:45:50 [ xNbcPool-1-thread-2:31855580 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 2 | 2017-03-07 02:46:02 [ xNbcPool-1-thread-2:31868168 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 3 | 2017-03-07 02:46:42 [ xNbcPool-1-thread-2:31908231 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 4 | 2017-03-07 02:46:52 [ xNbcPool-1-thread-2:31918205 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 5 | 2017-03-07 02:52:53 [ xNbcPool-1-thread-3:32279351 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 6 | 2017-03-07 02:53:07 [ xNbcPool-1-thread-3:32292604 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 7 | 2017-03-07 02:55:13 [ xNbcPool-1-thread-4:32419280 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 8 | 2017-03-07 02:55:23 [ xNbcPool-1-thread-4:32428545 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 9 | 2017-03-07 02:59:59 [ xNbcPool-1-thread-5:32705312 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 10 | 2017-03-07 03:00:03 [ xNbcPool-1-thread-5:32709294 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 11 | 2017-03-07 03:03:31 [ xNbcPool-1-thread-6:32917282 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 12 | 2017-03-07 03:03:33 [ xNbcPool-1-thread-6:32918812 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 13 | 2017-03-07 03:09:29 [ xNbcPool-1-thread-7:33274838 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 14 | 2017-03-07 03:09:33 [ xNbcPool-1-thread-7:33279029 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 15 | 2017-03-07 05:40:39 [ xNbcPool-1-thread-8:42344911 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 16 | 2017-03-07 05:40:43 [ xNbcPool-1-thread-8:42348624 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 17 | 2017-03-07 08:11:38 [ xNbcPool-1-thread-9:51404394 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 18 | 2017-03-07 08:11:43 [ xNbcPool-1-thread-9:51408765 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 19 | 2017-03-07 10:46:22 [ xNbcPool-1-thread-10:60688054 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 20 | 2017-03-07 10:57:00 [ xNbcPool-1-thread-11:61325586 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 21 | 2017-03-07 13:24:19 [ xNbcPool-1-thread-12:70165205 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 22 | 2017-03-07 13:24:23 [ xNbcPool-1-thread-12:70169053 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 23 | 2017-03-07 14:03:45 [ xNbcPool-1-thread-13:72531258 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 24 | 2017-03-07 14:03:51 [ xNbcPool-1-thread-13:72537014 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 25 | 2017-03-07 16:51:20 [ xNbcPool-1-thread-14:82585797 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 26 | 2017-03-07 16:51:34 [ xNbcPool-1-thread-14:82600343 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 27 | 2017-03-07 16:56:38 [ xNbcPool-1-thread-15:82904132 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 28 | 2017-03-07 16:56:41 [ xNbcPool-1-thread-15:82906567 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 29 | 2017-03-07 17:04:49 [ xNbcPool-1-thread-16:83395274 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 30 | 2017-03-07 17:05:06 [ xNbcPool-1-thread-16:83411609 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 31 | 2017-03-07 17:06:54 [ xNbcPool-1-thread-17:83520376 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 32 | 2017-03-07 17:06:59 [ xNbcPool-1-thread-17:83525264 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 33 | 2017-03-07 17:15:12 [ xNbcPool-1-thread-18:84017663 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 34 | 2017-03-07 17:15:20 [ xNbcPool-1-thread-18:84025560 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 35 | 2017-03-07 17:22:09 [ xNbcPool-1-thread-19:84435273 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 36 | 2017-03-07 17:22:20 [ xNbcPool-1-thread-19:84445643 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 37 | 2017-03-07 17:23:44 [ xNbcPool-1-thread-20:84530383 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 38 | 2017-03-07 17:23:49 [ xNbcPool-1-thread-20:84535079 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 39 | 2017-03-07 17:26:42 [ xNbcPool-1-thread-21:84707710 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 40 | 2017-03-07 17:26:49 [ xNbcPool-1-thread-21:84715214 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 41 | 2017-03-07 17:31:17 [ xNbcPool-1-thread-22:84982964 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 42 | 2017-03-07 17:31:20 [ xNbcPool-1-thread-22:84986012 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 43 | 2017-03-07 17:33:45 [ xNbcPool-1-thread-23:85131028 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 44 | 2017-03-07 17:33:50 [ xNbcPool-1-thread-23:85135486 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 45 | 2017-03-07 17:37:49 [ xNbcPool-1-thread-24:85374847 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 46 | 2017-03-07 17:38:16 [ xNbcPool-1-thread-24:85401920 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 47 | 2017-03-07 21:57:37 [ xNbcPool-1-thread-25:100962782 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 48 | 2017-03-07 21:57:50 [ xNbcPool-1-thread-25:100975836 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 49 | 2017-03-07 22:07:45 [ xNbcPool-1-thread-26:101570480 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 50 | 2017-03-07 22:07:56 [ xNbcPool-1-thread-26:101581631 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 51 | 2017-03-07 22:10:00 [ xNbcPool-1-thread-27:101706180 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 52 | 2017-03-07 22:10:05 [ xNbcPool-1-thread-27:101711195 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 53 | 2017-03-07 22:15:33 [ xNbcPool-1-thread-28:102038472 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 54 | 2017-03-07 22:15:36 [ xNbcPool-1-thread-28:102042125 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 55 | 2017-03-07 22:16:44 [ xNbcPool-1-thread-29:102110348 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 56 | 2017-03-07 22:16:46 [ xNbcPool-1-thread-29:102111424 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 57 | 2017-03-07 22:19:18 [ xNbcPool-1-thread-30:102263943 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 58 | 2017-03-07 22:19:26 [ xNbcPool-1-thread-30:102271525 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 59 | 2017-03-07 22:19:47 [ xNbcPool-1-thread-30:102293186 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 60 | 2017-03-07 22:20:29 [ xNbcPool-1-thread-30:102335330 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 61 | 2017-03-07 22:21:12 [ xNbcPool-1-thread-30:102377596 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 62 | 2017-03-07 22:21:22 [ xNbcPool-1-thread-30:102387830 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 63 | 2017-03-07 22:30:36 [ xNbcPool-1-thread-31:102941728 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 64 | 2017-03-07 22:30:49 [ xNbcPool-1-thread-31:102954671 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 65 | 2017-03-07 22:33:07 [ xNbcPool-1-thread-32:103093279 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 66 | 2017-03-07 22:33:09 [ xNbcPool-1-thread-32:103094775 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 67 | 2017-03-07 22:37:08 [ xNbcPool-1-thread-33:103334174 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 68 | 2017-03-07 22:37:19 [ xNbcPool-1-thread-33:103344887 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 69 | 2017-03-07 22:40:38 [ xNbcPool-1-thread-34:103544036 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 70 | 2017-03-07 22:40:39 [ xNbcPool-1-thread-34:103544496 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 71 | 2017-03-07 22:45:46 [ xNbcPool-1-thread-35:103851951 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 72 | 2017-03-07 22:46:08 [ xNbcPool-1-thread-35:103873870 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 73 | 2017-03-07 22:47:50 [ xNbcPool-1-thread-36:103975516 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 74 | 2017-03-07 22:47:59 [ xNbcPool-1-thread-36:103984750 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 75 | 2017-03-07 22:49:14 [ xNbcPool-1-thread-37:104059843 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 76 | 2017-03-07 22:49:19 [ xNbcPool-1-thread-37:104064826 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 77 | 2017-03-07 23:02:46 [ xNbcPool-1-thread-38:104872217 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 78 | 2017-03-07 23:02:54 [ xNbcPool-1-thread-38:104880098 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 79 | 2017-03-07 23:39:01 [ xNbcPool-1-thread-39:107046730 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 80 | 2017-03-07 23:39:13 [ xNbcPool-1-thread-39:107059128 ] - [ INFO ] remoteName 101.37.23.52 has connected ! 81 | 2017-03-07 23:51:30 [ xNbcPool-1-thread-39:107795751 ] - [ INFO ] remoteName 101.37.23.52 has disconnected ! 82 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/market/CreateMinuteKline.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.market; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.utils.HttpWebCollecter; 5 | import com.dangfm.stock.socketclient.utils.RedisCls; 6 | import org.json.JSONArray; 7 | import org.json.JSONException; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.Set; 12 | 13 | /** 14 | * 分钟线k线生成器 15 | * 主要是根据一分钟的k线生成5分15分30分60分钟k历史k线 16 | * Created by dangfm on 17/3/4. 17 | */ 18 | public class CreateMinuteKline extends Thread { 19 | public static final Logger logger = LoggerFactory.getLogger(CreateMinuteKline.class); 20 | // k线缓存地址 21 | private String cachePath = Config.klineSavePath; 22 | private static RedisCls localRedis = new RedisCls(); 23 | // 限制保存多少根历史K线 24 | private int maxKlineCount = 1000; // 最多保存一千根历史K线 25 | @Override 26 | public void run() { 27 | super.run(); 28 | // logger.info("开始生成分钟K线"); 29 | 30 | getAllStocks(); 31 | 32 | } 33 | 34 | /** 35 | * 同步行情数据过来一次 36 | * 37 | */ 38 | public void getAllStocks(){ 39 | Set s = localRedis.redis(Config.redisDB_Search).keys("*"); 40 | // logger.info("开始采集公司资料"+s.size()); 41 | Object[] list = s.toArray(); 42 | for (int i=0;i=0) { 45 | String[] a = key.split("\\|"); 46 | //logger.info(a[0]); 47 | if (a.length > 0) { 48 | key = a[0]; 49 | createMinuteKlineWithCode(key); 50 | System.out.println("" + key + " 分钟线生成完成" + i + "/" + list.length); 51 | } 52 | } 53 | } 54 | // getAllStocks_A(); 55 | 56 | } 57 | 58 | 59 | private void createMinuteKlineWithCode(String code){ 60 | // 首先获取今天一分钟原始数据 61 | JSONArray minuteData = getOldMinuteData(code, 1); 62 | // logger.info("拿到原始数据"+minuteData.toString()); 63 | // 将一分钟转换成其他分钟数据 64 | // 5分钟 65 | JSONArray minute5Data = returnMinuteData(minuteData,code,5); 66 | // 15分钟 67 | JSONArray minute15Data = returnMinuteData(minuteData,code,15); 68 | // 30分钟 69 | JSONArray minute30Data = returnMinuteData(minuteData, code, 30); 70 | // 60分钟 71 | JSONArray minute60Data = returnMinuteData(minuteData, code, 60); 72 | 73 | // 开始存储数据 74 | saveMinuteData(minute5Data,code,5); 75 | saveMinuteData(minute15Data,code,15); 76 | saveMinuteData(minute30Data,code,30); 77 | saveMinuteData(minute60Data,code,60); 78 | 79 | } 80 | 81 | private void saveMinuteData(JSONArray data,String code,int minute){ 82 | if (data==null) return; 83 | String newString = ""; 84 | // 存数据前要把旧数据取出来 85 | JSONArray oldMinuteData = getOldMinuteData(code,minute); 86 | if (oldMinuteData.length()>maxKlineCount){ 87 | // 超过一千,就去除一部分 88 | 89 | } 90 | if (oldMinuteData!=null && oldMinuteData.length()>0) { 91 | // 把数据拼起来然后一起存进去 92 | try { 93 | // 看看最新的日期 94 | JSONArray last = oldMinuteData.getJSONArray(oldMinuteData.length()-1); 95 | String lastDateTime = last.getString(0); 96 | lastDateTime = lastDateTime.substring(0,8); 97 | JSONArray first = data.getJSONArray(0); 98 | String firstDateTime = first.getString(0); 99 | firstDateTime = firstDateTime.substring(0,8); 100 | if (!lastDateTime.equals(firstDateTime)){ 101 | for (int i = 0; i < data.length(); i++) { 102 | JSONArray line = data.getJSONArray(i); 103 | oldMinuteData.put(line); 104 | line = null; 105 | } 106 | }else{ 107 | System.out.println("生成" + minute + "分钟k线的日期已经是最新的,无需生成"); 108 | return; 109 | } 110 | 111 | newString = oldMinuteData.toString(); 112 | } catch (JSONException e) { 113 | logger.error(e.toString()); 114 | } 115 | 116 | 117 | }else{ 118 | // 直接存储 119 | newString = data.toString(); 120 | 121 | } 122 | if (!newString.isEmpty()){ 123 | if (newString.length()>10) { 124 | // 存储 125 | String savePath = cachePath + "" + minute + "min/" + code.toUpperCase() + ".txt"; 126 | try { 127 | HttpWebCollecter.saveFile(savePath, newString); 128 | System.out.println("生成" + minute+"分钟k线成功"); 129 | } catch (Exception e) { 130 | logger.error(e.toString()); 131 | } 132 | } 133 | } 134 | } 135 | 136 | /** 137 | * 获取k线历史数据 138 | * @param code 139 | * @param minute 140 | * @return 141 | */ 142 | private JSONArray getOldMinuteData(String code,int minute){ 143 | String minCachePath = cachePath+""+minute+"min/"+code.toUpperCase()+".txt"; 144 | System.out.println(minute+"分钟原始数据路径"+minCachePath); 145 | String result = HttpWebCollecter.readFile(minCachePath); 146 | JSONArray line = new JSONArray(); 147 | try { 148 | if (result!=null) { 149 | if (!result.isEmpty()) { 150 | // 转换成json数组 151 | line = new JSONArray(result); 152 | } 153 | } 154 | } catch (JSONException e) { 155 | logger.error(e.toString()); 156 | } 157 | // 获取k线数据 158 | return line; 159 | } 160 | 161 | /** 162 | * 返回分钟k线 163 | * @param daysdatas 原始一分钟k线数据 164 | * @param code 股票代码 165 | * @param minute 返回的分钟类型 5=5分钟 15=15分钟,以此类推 166 | * @return 167 | */ 168 | private JSONArray returnMinuteData(JSONArray daysdatas,String code,int minute){ 169 | JSONArray newa = new JSONArray(); 170 | double mHeightPrice = 0.0; 171 | double mLowPrice = 100000000; 172 | double mVolumn = 0.0; 173 | double mVolumnPrice = 0.0; 174 | double mClosePrice = 0.0; 175 | double mOpenPrice = 0.0; 176 | String mStartDate = ""; 177 | double mYestodayClosePrice = 0; 178 | for (int i = 0; i < daysdatas.length(); i++) { 179 | try { 180 | JSONArray rs = daysdatas.getJSONArray(i); 181 | String datetime = rs.getString(0); 182 | String minstr = datetime.substring(10,12); 183 | int min = Integer.parseInt(minstr); 184 | int fenzhong = Integer.parseInt(datetime.substring(8,12)); 185 | if ((min%minute==0 && i>1) || (fenzhong==1030 && minute==60) || (fenzhong==1130 && minute==60)) { 186 | if (fenzhong==1000 && minute==60) { 187 | 188 | }else if (fenzhong==1100 && minute==60) { 189 | 190 | }else { 191 | JSONArray line = new JSONArray(); 192 | line.put(datetime); 193 | line.put(mYestodayClosePrice); 194 | line.put(mOpenPrice); 195 | line.put(mHeightPrice); 196 | line.put(mLowPrice); 197 | line.put(mClosePrice); 198 | line.put(mVolumn); 199 | line.put(mVolumnPrice); 200 | 201 | // 添加进数组 202 | newa.put(line); 203 | // 恢复初始化 204 | mHeightPrice = 0; 205 | mLowPrice = 100000000; 206 | mVolumn = 0; 207 | mVolumnPrice = 0; 208 | mClosePrice = 0; 209 | mOpenPrice = 0; 210 | mYestodayClosePrice = 0; 211 | } 212 | } 213 | if (rs.getDouble(3)>mHeightPrice) { 214 | mHeightPrice = rs.getDouble(3); 215 | } 216 | if (rs.getDouble(4)= 0) { 96 | String[] a = key.split("\\|"); 97 | if (a.length > 0) { 98 | key = a[0]; 99 | // initOnePoint(key); 100 | // System.out.println(key+" "+i+"/"+list.length); 101 | } 102 | } 103 | } catch (Exception e) { 104 | e.printStackTrace(); 105 | logger.error(e.toString()); 106 | } 107 | } 108 | } 109 | 110 | 111 | /** 112 | * 初始化所有分钟点 113 | * @param code 114 | */ 115 | private void initOnePoint(String code){ 116 | String key = code+"_today"; 117 | long startTime = FN.getTimeMillis("09:25:00"); 118 | for (int i=0;i<=335;i++){ 119 | if (i<=125 || i>215){ 120 | String filed = FN.getDateWithFormat("HHmm",new Date(startTime)); 121 | String value = ""; 122 | if (!filed.isEmpty()) { 123 | // 如果当前有了最新的就不要替换了 124 | String v = redis.getRedis().hget(key,filed); 125 | // logger.info(v); 126 | if (v!=null) { 127 | if (v.indexOf(",")>0) { 128 | String[] vs = v.split(","); 129 | // 拿到这个数据的日期 130 | String date = vs[0]; 131 | // 拿实时行情的日期 132 | JSONObject obj = FN.getRealtime(code,localRedis); 133 | if (obj!=null) { 134 | try { 135 | // logger.info(obj.toString()); 136 | if (obj.has("lastDate")) { 137 | String datetime = obj.getString("lastDate"); 138 | datetime = datetime.replace("-", ""); 139 | if (Integer.parseInt(date) == Integer.parseInt(datetime)) { 140 | // 是最新实时分钟行情就保留 141 | value = v; 142 | // logger.info("日期相同:"+v); 143 | } 144 | } 145 | } catch (JSONException e) { 146 | logger.error(e.toString()); 147 | } 148 | } 149 | obj = null; 150 | 151 | } 152 | } 153 | v = null; 154 | redis.getRedis().hset(key, filed, value); 155 | 156 | } 157 | filed = null; 158 | value = null; 159 | } 160 | startTime += 60 * 1000; 161 | } 162 | } 163 | 164 | 165 | private void createAll(){ 166 | redis.select(Config.redisDB_minKlineData); 167 | localRedis.select(Config.redisDB_market); 168 | JSONObject objlist = Config.realtimeStockDatas; 169 | // logger.debug("有多少个股票啊:"+objlist.length()); 170 | if (objlist.length()<=0) return; 171 | JSONArray list = objlist.names(); 172 | 173 | if (list.length()<=0) return; 174 | 175 | for (int i=0;i= 9) { 215 | int olddate = Integer.parseInt(one[0]); 216 | // 看看时间是不是当天的 217 | if (olddate == date) { 218 | open = Double.parseDouble(one[2]); 219 | high = Double.parseDouble(one[3]) > price ? Double.parseDouble(one[3]) : price; 220 | low = Double.parseDouble(one[4]) < price ? Double.parseDouble(one[4]) : price; 221 | close = price; 222 | startVolumn = Double.parseDouble(one[8]); 223 | } else { 224 | // 不是当天的时间就清理掉 225 | } 226 | } 227 | one = null; 228 | } 229 | } 230 | 231 | String value = date + "," + time + "," + open + "," + high + "," + low + "," + close + "," + volumn + "," + volumnPrice + "," + startVolumn; 232 | 233 | if (!filed.isEmpty()) { 234 | // logger.info(hKey+filed+value); 235 | // 更新这一分钟 236 | redis.getRedis().hset(hKey, filed, value); 237 | } 238 | value = null; 239 | } 240 | } 241 | } 242 | } catch (JSONException e) { 243 | e.printStackTrace(); 244 | logger.error(e.toString()); 245 | } 246 | obj = null; 247 | } 248 | json = null; 249 | } 250 | key = null; 251 | } catch (Exception e) { 252 | e.printStackTrace(); 253 | logger.error(e.toString()); 254 | } 255 | } 256 | list = null; 257 | objlist = null; 258 | } 259 | 260 | private void createOnePointKline(){ 261 | 262 | } 263 | } 264 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 大师兄股票实时行情客户端 2 | 3 | 客户端采用JAVA语言开发,支持Linux|Windows多平台运行,主要用来分发股市Level1实时行情。大师兄实时行情工具集成了股市实时行情,五档,财务数据以及板块涨跌幅榜,个股涨跌幅榜,日K、周K、月K、1分钟、5分钟、15分钟、30分钟、60分钟K线历史数据于一体,采用Redis缓存数据库进行存储,快速便捷。数据使用也非常方便,不用复杂的计算,基本都是拿来就用,任何人都无须股市知识的情况下灵活使用。现在推出公测版,因为服务器资源有限,视情况切断试用通道,理解万岁!!! 4 | 5 | 目前只支持A股行情,实时行情延时3秒左右 6 | 7 | 8 | 9 | ## 环境要求 10 | 1、JAVA JDK 1.8及以上,JDK下载地址: 11 | 12 | http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 13 | 14 | 2、安装Reids环境 15 | 16 | 下载地址https://redis.io/ 17 | 18 | 3、硬件要求: 19 | 20 | CPU 四核 8G内存及以上 21 | 22 | ## 配置文件 23 | 配置文件路径: 24 | 25 | 项目根目录/config.properties 26 | 27 | 配置文件内容: 28 | 29 | #本地redis 30 | 31 | redisServer = 127.0.0.1 32 | 33 | redisPort = 6379 34 | 35 | redisPassword = 123456 36 | 37 | #路由 不可修改 38 | 39 | socketServer = http://127.0.0.1:8111/v1/ 40 | 41 | #是否采集K线历史数据 42 | 43 | isCollectionHistoryKline = false 44 | 45 | #是否采集分钟K线历史数据 46 | 47 | isCollectionHistoryMinKline = false 48 | 49 | #k线本地保存地址 为空默认为程序运行目录 50 | 51 | klineSavePath = 52 | 53 | #注:第一次运行会自动注册并保存以下信息,如果IDE运行会每次被覆盖掉,请用命令行运行,运行后保存好config文件 54 | 55 | appId=1234 56 | 57 | appKey=daf57274235c4792ba0929ca12345678 58 | 59 | appSecret=356d73a37a2344cd91d369d8b12345678 60 | 61 | appPassword=12345678 62 | 63 | 64 | ## 运行命令 65 | 启动: 66 | 67 | java -jar /data/stocksocketclient/stocksocketclient.jar 68 | 69 | 重启: 70 | 71 | java -jar /data/stocksocketclient/stocksocketclient.jar 1 72 | 73 | 同步所有K线历史数据: 74 | 75 | java -jar /data/stocksocketclient/stocksocketclient.jar 3 76 | 77 | 78 | ## 数据结构 79 | 80 | 运行初始化后即可在redis找到实时行情数据,具体操作步骤如下: 81 | 82 | ### 1、获取某个股票实时行情数据: 83 | 84 | select 0 85 | 86 | get sh000001 87 | 88 | #返回json字符串: 89 | 90 | 91 | { 92 | "buy_1":0, 93 | "buy_2":0, 94 | "buy_3":0, 95 | "buy_4":0, 96 | "buy_5":0, 97 | "buy_1_s":530787800, 98 | "buy_2_s":0, 99 | "buy_3_s":0, 100 | "buy_4_s":0, 101 | "buy_5_s":0, 102 | "code":"sh000001", 103 | "closePrice":3154.65, 104 | "cityNetRate":0, 105 | "circulationValue":0, 106 | "highPrice":3156.73, 107 | "isStop":0, 108 | "lastDate":"2018-05-25", 109 | "lastTime":"15:01:03", 110 | "lowPrice":3131.07, 111 | "name":"上证指数", 112 | "openPrice":3148.41, 113 | "price":3141.3, 114 | "peRatio":0, 115 | "swing":0, 116 | "sell_1":0, 117 | "sell_2":0, 118 | "sell_3":0, 119 | "sell_4":0, 120 | "sell_5":0, 121 | "sell_1_s":621543700, 122 | "sell_2_s":0, 123 | "sell_3_s":0, 124 | "sell_4_s":0, 125 | "sell_5_s":0, 126 | "type":1, 127 | "totalValue":0, 128 | "turnoverRate":0, 129 | "volumn":12861084000, 130 | "volumnPrice":166554042368 131 | } 132 | 133 | #字段说明: 134 | name : 股票名称 135 | code : 股票代码 136 | type : 股票类型 0=普通A股 1=指数 137 | openPrice : 开盘价格 138 | closePrice : 昨日收盘价 139 | price : 当前价格 140 | highPrice : 最高价 141 | lowPrice : 最低价 142 | volumn : 成交量(股) 143 | volumnPrice : 成交额 144 | totalValue :总市值 145 | circulationValue :流通市值 146 | cityNetRate :市净率 147 | peRatio :市盈率 148 | swing : 振幅 149 | turnoverRate :换手率 150 | buy_1 : 买一价 151 | buy_2 : 买二价 152 | buy_3 : 买三价 153 | buy_4 : 买四价 154 | buy_5 : 买五价 155 | buy_1_s : 买一委托量(股) 156 | buy_2_s : 买二委托量 157 | buy_3_s : 买三委托量 158 | buy_4_s : 买四委托量 159 | buy_5_s : 买五委托量 160 | sell_1 : 卖一价 161 | sell_2 : 卖二价 162 | sell_3 : 卖三价 163 | sell_4 : 卖四价 164 | sell_5 : 卖五价 165 | sell_1_s : 卖一委托量 166 | sell_2_s : 卖二委托量 167 | sell_3_s : 卖三委托量 168 | sell_4_s : 卖四委托量 169 | sell_5_s : 卖五委托量 170 | lastDate : 最后更新日期 171 | lastTime : 最后更新时间 172 | 173 | 174 | ### 2、获取股票搜索库 175 | 176 | select 2 177 | 178 | keys * 179 | 180 | 搜索某个关键词股票 181 | 182 | keys xxx 183 | 184 | 返回结果: 185 | 186 | #示例 187 | #股票代码|拼音简称|股票名称|类型(0:个股,1:指数) 188 | sh000108|380xf|380消费|1 189 | sh600019|bggf|宝钢股份|0 190 | sh000010|sz180|上证180|1 191 | sh000122|nyzt|农业主题|1 192 | sh000145|yszy|优势资源|1 193 | sh000101|5nxy|5年信用|1 194 | sz300016|blyy|北陆药业|0 195 | sz000013|*stsha|*ST石化A|0 196 | 197 | 198 | ### 3、板块涨幅榜 199 | 200 | 201 | select 8 202 | 203 | 3.1、行业涨幅 204 | 205 | get Hangye_UpListKey 206 | 207 | 返回数据: 208 | 209 | 210 | [ 211 | { 212 | "code": "sz002617", 213 | "rate": 2.869056714423142, 214 | "change": 4.46, 215 | "name": "露笑科技", 216 | "id": "10000024", 217 | "title": "有色金属", 218 | "changeRate": 10.123456790123461 219 | }, 220 | { 221 | "code": "sh600983", 222 | "rate": 2.0594379730205024, 223 | "change": 5.82, 224 | "name": "惠而浦", 225 | "id": "10000012", 226 | "title": "家电行业", 227 | "changeRate": 2.826855123674914 228 | }, 229 | 230 | ] 231 | 232 | #字段说明: 233 | id : 行业编号 234 | title : 行业名称 235 | rate :行业涨幅 236 | code :股票代码 237 | name :股票名称 238 | change :股票涨跌额 239 | changeRate :股票涨跌幅百分比 240 | 241 | #### 3.2、概念涨幅 242 | 243 | get Gainian_UpListKey 244 | 245 | 返回数据: 246 | 247 | 248 | [ 249 | { 250 | "code": "sz002237", 251 | "rate": 4.225965075707311, 252 | "change": 17.21, 253 | "name": "恒邦股份", 254 | "id": "1111111", 255 | "title": "黄金概念", 256 | "changeRate": 6.894409937888195 257 | }, 258 | { 259 | "code": "sz002554", 260 | "rate": 2.6858786703475914, 261 | "change": 3.66, 262 | "name": "惠博普", 263 | "id": "11111165", 264 | "title": "可燃冰", 265 | "changeRate": 5.475504322766569 266 | }, 267 | 268 | ] 269 | 270 | #字段说明: 271 | id : 概念编号 272 | title : 概念名称 273 | rate :概念涨幅 274 | code :股票代码 275 | name :股票名称 276 | change :股票涨跌额 277 | changeRate :股票涨跌幅百分比 278 | 279 | #### 3.3、地域涨幅 280 | 281 | get Diqu_UpListKey 282 | 283 | 返回数据: 284 | 285 | 286 | [ 287 | { 288 | "code": "sz000975", 289 | "rate": 1.8884066689198225, 290 | "change": 13.42, 291 | "name": "银泰资源", 292 | "id": "2222222", 293 | "title": "内蒙古自治区", 294 | "changeRate": 6.847133757961779 295 | }, 296 | { 297 | "code": "sh600759", 298 | "rate": 1.400824359077736, 299 | "change": 3.65, 300 | "name": "洲际油气", 301 | "id": "2222228", 302 | "title": "海南省", 303 | "changeRate": 7.988165680473373 304 | }, 305 | { 306 | "code": "sz002237", 307 | "rate": 1.3713239408760203, 308 | "change": 17.27, 309 | "name": "恒邦股份", 310 | "id": "2222224", 311 | "title": "山东省", 312 | "changeRate": 7.2670807453416035 313 | }, 314 | 315 | ] 316 | 317 | #字段说明: 318 | id : 地域编号 319 | title : 地域名称 320 | rate :地域涨幅 321 | code :股票代码 322 | name :股票名称 323 | change :股票涨跌额 324 | changeRate :股票涨跌幅百分比 325 | 326 | #### 3.4、个股涨幅榜 327 | 328 | get Stock_UpdownList 329 | 330 | 返回数据: 331 | 332 | { 333 | "sz002617": 10.123456790123461, 334 | "sz300019": 10.069930069930066, 335 | "sz300697": 10.027855153203353, 336 | "sz300206": 10.02747252747252, 337 | "sh601698": 10.023866348448685, 338 | "sz300788": 10.01405481377371, 339 | "sh601236": 9.954751131221721, 340 | "sz300162": 7.812499999999996, 341 | "sh601808": 7.104984093319193, 342 | "sz002177": 6.434782608695653, 343 | } 344 | 345 | #字段说明 346 | 股票代码 :涨跌百分比 347 | 348 | 349 | #### 3.5、换手率榜 350 | 351 | get Stock_UpdownList_turnoverRate 352 | 353 | 返回数据: 354 | 355 | { 356 | "sh603867": 33.23, 357 | "sz300554": 30.26, 358 | "sz300717": 12.98, 359 | "sh603738": 12.64, 360 | "sz300697": 12.42, 361 | "sz002865": 12.02, 362 | "sh603283": 11.57, 363 | } 364 | #股票代码:换手率百分比 365 | 366 | 367 | #### 3.6、振幅榜 368 | 369 | get Stock_UpdownList_swing 370 | 371 | 返回数据: 372 | 373 | { 374 | "sh600078": 12.18, 375 | "sz300700": 11.84, 376 | "sz300385": 11.78, 377 | "sh603937": 11.06, 378 | "sh600592": 10.83, 379 | } 380 | #股票代码:振幅百分比 381 | 382 | 383 | #### 3.7、总市值排行榜 384 | 385 | get Stock_UpdownList_totalValue 386 | 387 | 返回数据: 388 | 389 | { 390 | "sh601398": 14990.44, 391 | "sh600519": 12342.39, 392 | "sh601857": 10832.59, 393 | "sh601288": 10556.59, 394 | "sh601318": 9574.99, 395 | } 396 | #股票代码:市值(单位:亿) 397 | 398 | 399 | #### 3.8、流通市值排行 400 | 401 | get Stock_UpdownList_circulationValue 402 | 403 | 返回数据: 404 | 405 | { 406 | "sh601398": 14990.44, 407 | "sh600519": 12342.39, 408 | "sh601857": 10832.59, 409 | "sh601288": 10556.59, 410 | "sh601318": 9574.99, 411 | } 412 | #股票代码:市值(单位:亿) 413 | 414 | 415 | ### 4、除权数据 416 | 417 | hgetall ExRight_Tables 418 | 419 | hget ExRight_Tables 600000 420 | 421 | 返回数据: 422 | 423 | [ 424 | { 425 | "code":"600000", 426 | "datetime":"2000-07-06", 427 | "give":0, 428 | "pei":0, 429 | "peiPrice":0, 430 | "profile":0.15000000596046448 431 | }, 432 | { 433 | "code":"600000", 434 | "datetime":"2002-08-22", 435 | "give":0.5, 436 | "pei":0, 437 | "peiPrice":0, 438 | "profile":0.20000000298023224 439 | } 440 | ] 441 | 442 | 443 | #字段含义: 444 | code:股票代码 445 | datetime:日期 446 | give:每股送 447 | pei:每股配 448 | peiPrice:配股价 449 | profile:每股红利 450 | 451 | ### 5、财务数据 452 | 453 | hgetall Financial_Tables 454 | 455 | hget Financial_Tables 600000 456 | 457 | 返回数据: 458 | 459 | { 460 | "code":"600000", 461 | "datetime":"20180830", 462 | "ZGB":"2935208.00", 463 | "GJG":"180199.00", 464 | "LTAG":"2810376.50", 465 | "ZZC":"6091758592.0", 466 | "LDZC":"0.0", 467 | "GDZC":"31543000.0", 468 | "JZC":"440855008.0", 469 | "ZYSY":"82256000.0", 470 | "ZYLY":"0.0", 471 | "YYLY":"34164000.0", 472 | "SHLY":"28900000.0", 473 | "JLY":"28569000.0", 474 | "DY":" 16", 475 | "HY":" 1", 476 | "ZBNB":"6", 477 | "SSDATE":"19991110" 478 | } 479 | 480 | #字段说明: 481 | code:股票代码 482 | datetime:日期 483 | ZGB:总股本 484 | GJG:国家股 485 | LTAG:流通A股 486 | ZZC:总资产 487 | LDZC:流动资产 488 | GDZC:固定资产 489 | JZC:净资产 490 | ZYSY:营业收入 491 | ZYLY:主营利润 492 | YYLY:营业利润 493 | SHLY:税后利润 494 | JLY:净利润 495 | DY:地域 496 | HY:行业 497 | ZBNB:资料月份 9 代表三季报 12代表年报 498 | SSDATE:上市日期 499 | 500 | 501 | 502 | 503 | ## 使用文档: 504 | 505 | http://www.gjl.info/quotes/ 506 | 507 | 508 | ## 下载地址 509 | 510 | 官方更新地址: 511 | 512 | https://github.com/dangfm/stocksoketclient/ 513 | 514 | 接口DEMO:https://github.com/dangfm/KLineApi 515 | 516 | 移动端DEMO:https://app.download.hemyun.com/cloudstrategy/ 517 | 518 | QQ交流群:大师兄股票实时行情 519 | 520 | 群 号:789599606 521 | 522 | 523 | 524 | 仅供学习研究使用,请勿用于商业用途! 525 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/utils/HttpWebCollecter.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.utils; 2 | import org.apache.http.HttpResponse; 3 | import org.apache.http.client.HttpClient; 4 | import org.apache.http.client.methods.HttpPost; 5 | import org.apache.http.entity.StringEntity; 6 | import org.apache.http.impl.client.HttpClients; 7 | 8 | import java.io.*; 9 | import java.net.HttpURLConnection; 10 | import java.net.URL; 11 | import java.net.URLConnection; 12 | import java.util.ArrayList; 13 | import java.util.List; 14 | import java.util.Map; 15 | import java.util.regex.Matcher; 16 | import java.util.regex.Pattern; 17 | 18 | public class HttpWebCollecter { 19 | 20 | protected final static String USER_AGENT = "Mozilla/5.0"; 21 | 22 | /** 23 | * 向指定URL发送GET方法的请求 24 | * 25 | * @param url 26 | * 发送请求的URL 27 | * @param param 28 | * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 29 | * @return URL 所代表远程资源的响应结果 30 | */ 31 | public static String sendGet(String url, String param) { 32 | String result = ""; 33 | BufferedReader in = null; 34 | try { 35 | String urlNameString = url + "?" + param; 36 | URL realUrl = new URL(urlNameString); 37 | // 打开和URL之间的连接 38 | URLConnection connection = realUrl.openConnection(); 39 | // 设置通用的请求属性 40 | connection.setRequestProperty("accept", "*/*"); 41 | connection.setRequestProperty("connection", "Keep-Alive"); 42 | connection.setRequestProperty("user-agent", 43 | "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); 44 | // 建立实际的连接 45 | connection.connect(); 46 | // 获取所有响应头字段 47 | Map> map = connection.getHeaderFields(); 48 | // 遍历所有的响应头字段 49 | for (String key : map.keySet()) { 50 | System.out.println(key + "--->" + map.get(key)); 51 | } 52 | // 定义 BufferedReader输入流来读取URL的响应 53 | in = new BufferedReader(new InputStreamReader( 54 | connection.getInputStream())); 55 | String line; 56 | while ((line = in.readLine()) != null) { 57 | result += line; 58 | } 59 | } catch (Exception e) { 60 | System.out.println("发送GET请求出现异常!" + e); 61 | e.printStackTrace(); 62 | } 63 | // 使用finally块来关闭输入流 64 | finally { 65 | try { 66 | if (in != null) { 67 | in.close(); 68 | } 69 | } catch (Exception e2) { 70 | e2.printStackTrace(); 71 | } 72 | } 73 | return result; 74 | } 75 | 76 | /** 77 | * 向指定 URL 发送POST方法的请求 78 | * 79 | * @param pathUrl 80 | * 发送请求的 URL 81 | * @param param 82 | * 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 83 | * @return 所代表远程资源的响应结果 84 | */ 85 | public static String sendPost(String pathUrl, String param) { 86 | String result = ""; 87 | String url = pathUrl; 88 | HttpPost post = new HttpPost(url); 89 | post.setHeader("user-Agent", USER_AGENT); 90 | StringEntity se = new StringEntity(param, "UTF-8"); 91 | post.setEntity(se); 92 | // Send the post request and get the response 93 | HttpResponse response = null; 94 | try { 95 | HttpClient httpclient = HttpClients.createDefault(); 96 | response = httpclient.execute(post); 97 | int status = response.getStatusLine().getStatusCode(); 98 | System.out.println("Response Code : " + status); 99 | BufferedReader rd = null; 100 | rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent())); 101 | StringBuffer sb = new StringBuffer(); 102 | String line = ""; 103 | while ((line = rd.readLine()) != null) { 104 | sb.append(line); 105 | } 106 | System.out.println(sb.toString()); 107 | if (status == 200) { 108 | System.out.println("Notification sent successfully."); 109 | } else { 110 | System.out.println("Failed to send the notification!"); 111 | } 112 | result = sb.toString(); 113 | } catch (IOException e) { 114 | e.printStackTrace(); 115 | } 116 | 117 | 118 | return result; 119 | } 120 | 121 | 122 | /** 123 | * 网页抓取方法 124 | * 125 | * @param urlString 126 | * 要抓取的url地址 127 | * @param charset 128 | * 网页编码方式 129 | * @param timeout 130 | * 超时时间 131 | * @return 抓取的网页内容 132 | * @throws IOException 133 | * 抓取异常 134 | */ 135 | public static String GetWebContent(String urlString, final String charset, 136 | int timeout) throws IOException { 137 | if (urlString == null || urlString.length() == 0) { 138 | return ""; 139 | } 140 | urlString = (urlString.startsWith("http://") || urlString 141 | .startsWith("https://")) ? urlString : ("http://" + urlString) 142 | .intern(); 143 | URL url = new URL(urlString); 144 | HttpURLConnection conn = (HttpURLConnection) url.openConnection(); 145 | conn.setDoOutput(true); 146 | conn.setRequestProperty("Pragma", "no-cache"); 147 | conn.setRequestProperty("Cache-Control", "no-cache"); 148 | 149 | int temp = Integer.parseInt(Math.round(Math.random() 150 | * (UserAgent.length - 1)) 151 | + ""); 152 | //conn.setRequestProperty("user-Agent", UserAgent[temp]); // 模拟手机系统 153 | conn.setRequestProperty("Accept", 154 | "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");// 只接受text/html类型,当然也可以接受图片,pdf,*/*任意,就是tomcat/conf/web里面定义那些 155 | conn.setConnectTimeout(timeout); 156 | try { 157 | if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) { 158 | return ""; 159 | } 160 | } catch (Exception e) { 161 | try { 162 | System.out.println(e.getMessage()); 163 | } catch (Exception e2) { 164 | e2.printStackTrace(); 165 | } 166 | return ""; 167 | } 168 | InputStream input = conn.getInputStream(); 169 | BufferedReader reader = new BufferedReader(new InputStreamReader(input, 170 | charset)); 171 | String line = null; 172 | StringBuffer sb = new StringBuffer(""); 173 | while ((line = reader.readLine()) != null) { 174 | sb.append(line).append("\r\n"); 175 | } 176 | if (reader != null) { 177 | reader.close(); 178 | } 179 | if (conn != null) { 180 | conn.disconnect(); 181 | } 182 | return sb.toString(); 183 | } 184 | 185 | public static String[] UserAgent = { 186 | "Mozilla/5.0 (Linux; U; Android 2.2; en-us; Nexus One Build/FRF91) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.2", 187 | "Mozilla/5.0 (iPad; U; CPU OS 3_2_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B500 Safari/531.21.11", 188 | "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/20.0.019; Profile/MIDP-2.1 Configuration/CLDC-1.1) AppleWebKit/525 (KHTML, like Gecko) BrowserNG/7.1.18121", 189 | "Nokia5700AP23.01/SymbianOS/9.1 Series60/3.0", 190 | "UCWEB7.0.2.37/28/998", "NOKIA5700/UCWEB7.0.2.37/28/977", 191 | "Openwave/UCWEB7.0.2.37/28/978", 192 | "Mozilla/4.0 (compatible; MSIE 6.0; ) Opera/UCWEB7.0.2.37/28/989" 193 | }; 194 | 195 | public static String getWebContent(String domain){ 196 | // System.out.println("开始读取内容...("+domain+")"); 197 | StringBuffer sb = new StringBuffer(); 198 | try{ 199 | URL url = new URL(domain); 200 | BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); 201 | String line; 202 | while((line = in.readLine()) != null){ 203 | sb.append(line); 204 | } 205 | in.close(); 206 | }catch(Exception e) { 207 | // Report any errors that arise 208 | // sb.append(e.toString()); 209 | System.err.println(e); 210 | System.err.println("Usage: java HttpClient []"); 211 | } 212 | return sb.toString(); 213 | } 214 | 215 | /** 216 | * 下载文件或图片到本地存储 217 | * @param urlString 218 | * @param filename 219 | * @param savePath 220 | * @throws Exception 221 | */ 222 | public static String download(String urlString, String filename,String savePath) throws Exception { 223 | // 构造URL 224 | URL url = new URL(urlString); 225 | // 打开连接 226 | URLConnection con = url.openConnection(); 227 | //设置请求超时为5s 228 | con.setConnectTimeout(5*1000); 229 | // 输入流 230 | InputStream is = con.getInputStream(); 231 | 232 | // 1K的数据缓冲 233 | byte[] bs = new byte[1024]; 234 | // 读取到的数据长度 235 | int len; 236 | // 输出的文件流 237 | File sf=new File(savePath); 238 | //判断目标文件所在的目录是否存在 239 | // if(!sf.getParentFile().exists()) { 240 | // //如果目标文件所在的目录不存在,则创建父目录 241 | // System.out.println("目标文件所在目录不存在,准备创建它!"); 242 | // if(!sf.getParentFile().mkdirs()) { 243 | // System.out.println("创建目标文件所在目录失败!"); 244 | // return null; 245 | // } 246 | // } 247 | if(!sf.exists()){ 248 | sf.mkdirs(); 249 | 250 | } 251 | sf.setWritable(true,false); 252 | try { 253 | OutputStream os = new FileOutputStream(sf.getPath()+"/"+filename); 254 | // 开始读取 255 | while ((len = is.read(bs)) != -1) { 256 | os.write(bs, 0, len); 257 | } 258 | // 完毕,关闭所有链接 259 | //System.out.println(sf.getPath() + "/" + filename); 260 | os.close(); 261 | is.close(); 262 | return filename; 263 | }catch (Exception e){ 264 | System.out.println(e); 265 | is.close(); 266 | return ""; 267 | } 268 | 269 | 270 | //return filename; 271 | } 272 | public static final Pattern PATTERN = Pattern.compile("]*)src\\s*=\\s*([^>]+)",Pattern.CASE_INSENSITIVE|Pattern.MULTILINE); 273 | 274 | public static List getImgSrc(String html){ 275 | Matcher matcher = PATTERN.matcher(html); 276 | List list = new ArrayList(); 277 | while (matcher.find()) { 278 | String group = matcher.group(1); 279 | if(group == null){ 280 | continue; 281 | } 282 | // 这里可能还需要更复杂的判断,用以处理src="...."内的一些转义符 283 | if(group.startsWith("'")){ 284 | list.add(group.substring(1,group.indexOf("'",1))); 285 | }else if (group.startsWith("\"")){ 286 | list.add(group.substring(1,group.indexOf("\"",1))); 287 | }else{ 288 | list.add(group.split("\\s")[0]); 289 | } 290 | } 291 | return list; 292 | } 293 | 294 | // /*** 295 | // * 获取ImageSrc地址 296 | // * 297 | // * @param listImageUrl 298 | // * @return 299 | // */ 300 | // public static List getImageSrc(List listImageUrl,String imgTag) { 301 | // List listImgSrc = new ArrayList(); 302 | // for (String image : listImageUrl) { 303 | // Matcher matcher = Pattern.compile(imgTag).matcher(image); 304 | // while (matcher.find()) { 305 | // listImgSrc.add(matcher.group().substring(0, matcher.group().length() - 1)); 306 | // } 307 | // } 308 | // return listImgSrc; 309 | // } 310 | 311 | 312 | public static String readFile(String filePath){ 313 | BufferedReader br = null; 314 | String value = ""; 315 | try { 316 | File sf=new File(filePath); 317 | //判断目标文件所在的目录是否存在 318 | if(!sf.getParentFile().exists()) { 319 | //如果目标文件所在的目录不存在,则创建父目录 320 | //System.out.println("目标文件所在目录不存在,准备创建它!"); 321 | if(!sf.getParentFile().mkdirs()) { 322 | System.out.println("创建目标文件所在目录失败!"+filePath); 323 | //return null; 324 | } 325 | } 326 | if (sf.exists()) { 327 | br = new BufferedReader(new FileReader(filePath)); 328 | StringBuffer sb = new StringBuffer(); 329 | String line = null; 330 | while ((line = br.readLine()) != null) { 331 | sb.append(line); 332 | } 333 | value = sb.toString(); 334 | } 335 | } catch (FileNotFoundException e) { 336 | e.printStackTrace(); 337 | } catch (IOException e) { 338 | e.printStackTrace(); 339 | } 340 | 341 | return value; 342 | } 343 | 344 | /** 345 | * 保存文件内容到本地存储 346 | * @param savePath 347 | * @param datas 348 | * @throws Exception 349 | */ 350 | public static void saveFile(String savePath,String datas) throws Exception { 351 | // 输出的文件流 352 | File sf=new File(savePath); 353 | //判断目标文件所在的目录是否存在 354 | if(!sf.getParentFile().exists()) { 355 | //如果目标文件所在的目录不存在,则创建父目录 356 | //System.out.println("目标文件所在目录不存在,准备创建它!"); 357 | if(!sf.getParentFile().mkdirs()) { 358 | System.out.println("创建目标文件所在目录失败!"+savePath); 359 | //return null; 360 | } 361 | } 362 | if(!sf.exists()){ 363 | //sf.mkdirs(); 364 | sf.createNewFile(); 365 | } 366 | sf.setWritable(true,false); 367 | try { 368 | FileWriter fw = new FileWriter(sf.getAbsoluteFile()); 369 | BufferedWriter bw = new BufferedWriter(fw); 370 | bw.write(datas); 371 | bw.close(); 372 | }catch (Exception e){ 373 | System.out.println(e); 374 | } 375 | 376 | 377 | //return filename; 378 | } 379 | } 380 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/server/StockResposeDatas.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.server; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.market.InitAllStockDatas; 5 | import com.dangfm.stock.socketclient.market.SaveAllStocks; 6 | import com.dangfm.stock.socketclient.market.SaveKlineDatas; 7 | import com.dangfm.stock.socketclient.user.UserHelper; 8 | import com.dangfm.stock.socketclient.utils.FN; 9 | import com.dangfm.stock.socketclient.utils.FileHelper; 10 | import com.dangfm.stock.socketclient.utils.RedisCls; 11 | import com.dangfm.stock.socketclient.utils.ZipUtils; 12 | import com.sun.org.apache.xml.internal.security.Init; 13 | import org.json.JSONArray; 14 | import org.json.JSONException; 15 | import org.json.JSONObject; 16 | import org.slf4j.Logger; 17 | import org.slf4j.LoggerFactory; 18 | import org.xsocket.connection.INonBlockingConnection; 19 | import redis.clients.jedis.Pipeline; 20 | import redis.clients.jedis.Protocol; 21 | 22 | import java.io.IOException; 23 | import java.io.UnsupportedEncodingException; 24 | import java.lang.reflect.Array; 25 | import java.net.URLDecoder; 26 | import java.util.ArrayList; 27 | import java.util.Date; 28 | import java.util.List; 29 | import java.util.concurrent.locks.ReentrantLock; 30 | 31 | public class StockResposeDatas { 32 | public static final Logger logger = LoggerFactory.getLogger(StockResposeDatas.class); 33 | 34 | private static ReentrantLock lock = new ReentrantLock(); 35 | 36 | /** 37 | 保存接收到的数据 38 | */ 39 | private static String datas; 40 | /** 41 | * 保存拿到的键值信息 42 | */ 43 | private static JSONArray names = new JSONArray(); 44 | /** 45 | * 保存拿到的股票行情 46 | */ 47 | private static JSONObject stockRealTimes = new JSONObject(); 48 | 49 | private static INonBlockingConnection nbc; 50 | 51 | /** 52 | * 本地redis 53 | */ 54 | private static RedisCls redisCls = new RedisCls(); 55 | private static Pipeline pipeline = redisCls.getRedis().pipelined(); 56 | 57 | 58 | /** 59 | * 解析类 60 | * @param data 61 | */ 62 | public static void StockResposeDatas(String data, INonBlockingConnection nbcs){ 63 | nbc = nbcs; 64 | if (Config.isConnected) { 65 | // 先url解码 66 | if (data.length()>0) { 67 | try { 68 | datas = data; 69 | float size = datas.getBytes().length / 1024; 70 | // 解压一下 71 | String str = ZipUtils.unzip(datas); 72 | 73 | float afterSize = str.getBytes().length / 1024; 74 | // logger.info("接收到数据,原大小:" + size + "k 解压后:" + afterSize + "k" + " "); 75 | if (str.startsWith("{")) { 76 | JSONObject obj = new JSONObject(str); 77 | // 协议和数据 78 | if (obj.has("protocol") && obj.has("data")) { 79 | // 协议名称 80 | String protocol = obj.getString("protocol"); 81 | // 数据 82 | String dataStr = obj.getString("data"); 83 | dataStr = URLDecoder.decode(dataStr,"UTF-8"); 84 | 85 | // logger.info(dataStr); 86 | /** 87 | * 解析注册 88 | */ 89 | if (protocol.equals(Config.protocol_register)) displayRegister(dataStr); 90 | /** 91 | * 解析登陆验证 92 | */ 93 | if (protocol.equals(Config.protocol_checklogin)) displayCheckLogin(dataStr); 94 | /** 95 | * 解析实时行情数据键值数据 96 | */ 97 | if (protocol.equals(Config.protocol_json_names)) displayJsonNames(dataStr); 98 | 99 | /** 100 | * 解析实时行情数据 101 | */ 102 | if (protocol.equals(Config.protocol_realtime)) displayRealtime(dataStr); 103 | /** 104 | * 解析股票行业板块 105 | */ 106 | if (protocol.equals(Config.protocol_hangye_tables)) displayAllStockTypes_hangye(dataStr); 107 | /** 108 | * 解析股票概念板块 109 | */ 110 | if (protocol.equals(Config.protocol_gainian_tables)) displayAllStockTypes_gainian(dataStr); 111 | /** 112 | * 解析股票地区板块 113 | */ 114 | if (protocol.equals(Config.protocol_diqu_tables)) displayAllStockTypes_diqu(dataStr); 115 | /** 116 | * 解析股票分类表 117 | */ 118 | if (protocol.equals(Config.protocol_allstocks)) displayAllStocks(dataStr); 119 | /** 120 | * 解析股票搜索表 121 | */ 122 | if (protocol.equals(Config.protocol_searchstocks)) displaySearchStocks(dataStr); 123 | 124 | /** 125 | * 解析当天日k历史行情数据 126 | */ 127 | if (protocol.equals(Config.protocol_todayKline)) displayTodayKlineData(dataStr); 128 | if (protocol.equals(Config.protocol_todayKline_before)) displayTodayKlineData_before(dataStr); 129 | if (protocol.equals(Config.protocol_todayKline_after)) displayTodayKlineData_after(dataStr); 130 | 131 | /** 132 | * 解析当天1分钟历史行情数据 133 | */ 134 | if (protocol.equals(Config.protocol_today1MinuteKline)) displayToday1MinuteKlineData(dataStr); 135 | if (protocol.equals(Config.protocol_today1MinuteKline_before)) displayToday1MinuteKlineData_before(dataStr); 136 | if (protocol.equals(Config.protocol_today1MinuteKline_after)) displayToday1MinuteKlineData_after(dataStr); 137 | } 138 | 139 | 140 | obj = null; 141 | 142 | } 143 | } catch (JSONException e) { 144 | logger.error(e.toString()); 145 | } catch (UnsupportedEncodingException e) { 146 | logger.error(e.toString()); 147 | } 148 | } 149 | } 150 | } 151 | 152 | /** 153 | * 解析注册 154 | * @param data 155 | */ 156 | private static void displayRegister(String data){ 157 | if (data.length()>0) { 158 | try { 159 | if (data.startsWith("{")) { 160 | JSONObject obj = new JSONObject(data); 161 | int error = obj.getInt("error"); 162 | String msg = obj.getString("msg"); 163 | logger.info(msg); 164 | if (error > 0) { 165 | // 注册失败 166 | 167 | }else{ 168 | // 注册成功会发送这个app_key app_secret 169 | UserHelper.register(msg,nbc); 170 | 171 | } 172 | } 173 | } catch (JSONException e) { 174 | logger.error(e.toString()); 175 | } 176 | } 177 | 178 | } 179 | 180 | /** 181 | * 解析登陆验证 182 | * @param data 183 | */ 184 | private static void displayCheckLogin(String data){ 185 | if (data.length()>0) { 186 | try { 187 | if (data.startsWith("{")) { 188 | JSONObject obj = new JSONObject(data); 189 | int error = obj.getInt("error"); 190 | String msg = obj.getString("msg"); 191 | logger.info(obj.toString()); 192 | if (error > 0) { 193 | Config.isreConnected = false; 194 | }else{ 195 | // 登陆成功 196 | StockClientHeart.StockClientHeart(nbc); 197 | // 初始化数据 198 | InitAllStockDatas initAllStockDatas = new InitAllStockDatas(); 199 | initAllStockDatas.start(); 200 | } 201 | } 202 | } catch (JSONException e) { 203 | logger.error(e.toString()); 204 | } 205 | } 206 | 207 | } 208 | 209 | /** 210 | * 解析键值信息 211 | * @param data 212 | */ 213 | private static void displayJsonNames(String data){ 214 | try { 215 | names.put(0,new JSONArray(data)); 216 | 217 | } catch (JSONException e) { 218 | logger.error(e.toString()); 219 | } 220 | } 221 | 222 | /** 223 | * 解析实时行情 224 | * @param str 225 | */ 226 | private static void displayRealtime(String str){ 227 | try { 228 | JSONObject obj = new JSONObject(str); 229 | String stockCode = ""; 230 | JSONArray namekeys = names.getJSONArray(0); 231 | if (obj!=null) { 232 | String lastTime = ""; 233 | String lastDate = ""; 234 | String key = obj.names().getString(0); 235 | if (obj.has(key)) { 236 | String sh000001_obj = null; 237 | sh000001_obj = obj.getString(key); 238 | JSONObject shObj = FN.stoObj(sh000001_obj, namekeys); 239 | if (shObj.length()>0) { 240 | lastTime = shObj.getString("lastTime"); 241 | lastDate = shObj.getString("lastDate"); 242 | stockCode = shObj.getString("code"); 243 | // logger.info("接收到键值"+ namekeys); 244 | // logger.info(shObj.toString()); 245 | } 246 | shObj = null; 247 | sh000001_obj = null; 248 | } 249 | 250 | 251 | 252 | // 写入redis 253 | JSONArray keys = obj.names(); 254 | for (int i=0;i0) { 261 | stockRealTimes.put(code, shObj); 262 | /** 263 | * 这里写入redis 264 | */ 265 | // redisCls.setValue(code, shObj.toString()); 266 | pipeline.set(code,shObj.toString()); 267 | 268 | } 269 | jsonStr = null; 270 | shObj = null; 271 | 272 | } 273 | code = null; 274 | } 275 | pipeline.sync(); 276 | pipeline.clear(); 277 | //pipeline.close(); 278 | 279 | // 共享给其他服务用 280 | Config.realtimeStockDatas = obj; 281 | 282 | Date d1 = FN.strToDate(lastDate+" "+lastTime,"yyyy-MM-dd HH:mm:ss"); 283 | Date d2 = new Date(); 284 | double s = (d2.getTime() - d1.getTime()); 285 | 286 | // logger.info(obj.toString()); 287 | // logger.info("接收到实时行情"+keys.length()+"笔 "+stockCode+"最新时间:" + lastTime+" 当前时间:"+FN.getDateWithFormat("HH:mm:ss",new Date())+" 总共"+stockRealTimes.length()+"个股票"); 288 | System.out.println("接收到实时行情"+keys.length()+"笔 "+stockCode+"最新时间:" + lastTime+" 当前时间:"+FN.getDateWithFormat("HH:mm:ss",new Date())+" 延时"+String.format("%.2f",s)+"毫秒 总共"+stockRealTimes.length()+"个股票"); 289 | keys = null; 290 | } 291 | obj = null; 292 | } catch (JSONException e) { 293 | logger.error(e.toString()); 294 | } 295 | 296 | } 297 | 298 | /** 299 | * 解析当天日K历史数据 300 | * @param data 301 | */ 302 | private static void displayTodayKlineData(String data){ 303 | try { 304 | JSONObject obj = new JSONObject(data); 305 | String code = obj.names().getString(0); 306 | String value = obj.getString(code); 307 | 308 | SaveKlineDatas.saveDayKline(code,value,"datas"); 309 | 310 | } catch (JSONException e) { 311 | logger.error(e.toString()); 312 | } 313 | } 314 | private static void displayTodayKlineData_before(String data){ 315 | try { 316 | JSONObject obj = new JSONObject(data); 317 | String code = obj.names().getString(0); 318 | String value = obj.getString(code); 319 | 320 | SaveKlineDatas.saveDayKline(code,value,"before"); 321 | 322 | } catch (JSONException e) { 323 | logger.error(e.toString()); 324 | } 325 | } 326 | private static void displayTodayKlineData_after(String data){ 327 | try { 328 | JSONObject obj = new JSONObject(data); 329 | String code = obj.names().getString(0); 330 | String value = obj.getString(code); 331 | 332 | SaveKlineDatas.saveDayKline(code,value,"after"); 333 | 334 | } catch (JSONException e) { 335 | logger.error(e.toString()); 336 | } 337 | } 338 | 339 | /** 340 | * 解析当天1分钟历史数据 341 | * @param data 342 | */ 343 | private static void displayToday1MinuteKlineData(String data){ 344 | try { 345 | JSONObject obj = new JSONObject(data); 346 | String code = obj.names().getString(0); 347 | String value = obj.getString(code); 348 | 349 | SaveKlineDatas.saveMinuteKline(code,value,"datas"); 350 | 351 | } catch (JSONException e) { 352 | logger.error(e.toString()); 353 | } 354 | 355 | } 356 | private static void displayToday1MinuteKlineData_before(String data){ 357 | try { 358 | JSONObject obj = new JSONObject(data); 359 | String code = obj.names().getString(0); 360 | String value = obj.getString(code); 361 | SaveKlineDatas.saveMinuteKline(code,value,"before"); 362 | } catch (JSONException e) { 363 | logger.error(e.toString()); 364 | } 365 | } 366 | private static void displayToday1MinuteKlineData_after(String data){ 367 | try { 368 | JSONObject obj = new JSONObject(data); 369 | String code = obj.names().getString(0); 370 | String value = obj.getString(code); 371 | SaveKlineDatas.saveMinuteKline(code,value,"after"); 372 | } catch (JSONException e) { 373 | logger.error(e.toString()); 374 | } 375 | } 376 | 377 | /** 378 | * 解析股票板块表 行业板块 379 | * @param data 380 | */ 381 | private static void displayAllStockTypes_hangye(String data){ 382 | try { 383 | JSONArray obj = new JSONArray(data); 384 | SaveAllStocks.saveAllStockType_hangye(obj); 385 | } catch (JSONException e) { 386 | logger.error(e.toString()); 387 | } 388 | } 389 | 390 | /** 391 | * 解析股票板块表 概念板块 392 | * @param data 393 | */ 394 | private static void displayAllStockTypes_gainian(String data){ 395 | try { 396 | JSONArray obj = new JSONArray(data); 397 | SaveAllStocks.saveAllStockType_gainian(obj); 398 | } catch (JSONException e) { 399 | logger.error(e.toString()); 400 | } 401 | } 402 | 403 | /** 404 | * 解析股票板块表 地区板块 405 | * @param data 406 | */ 407 | private static void displayAllStockTypes_diqu(String data){ 408 | try { 409 | JSONArray obj = new JSONArray(data); 410 | SaveAllStocks.saveAllStockType_diqu(obj); 411 | } catch (JSONException e) { 412 | logger.error(e.toString()); 413 | } 414 | } 415 | 416 | /** 417 | * 解析股票分类表 418 | * @param data 419 | */ 420 | private static void displayAllStocks(String data){ 421 | try { 422 | JSONObject obj = new JSONObject(data); 423 | String key = obj.names().getString(0); 424 | String value = obj.getString(key); 425 | SaveAllStocks.saveAllStocks(key,value); 426 | } catch (JSONException e) { 427 | logger.error(e.toString()); 428 | } 429 | } 430 | 431 | /** 432 | * 解析股票搜索表 433 | * @param data 434 | */ 435 | private static void displaySearchStocks(String data){ 436 | try { 437 | JSONObject obj = new JSONObject(data); 438 | String key = obj.names().getString(0); 439 | String value = obj.getString(key); 440 | SaveAllStocks.saveSearchStocks(key,value); 441 | } catch (JSONException e) { 442 | logger.error(e.toString()); 443 | } 444 | } 445 | } 446 | -------------------------------------------------------------------------------- /src/com/dangfm/stock/socketclient/market/GetStockDaysLine.java: -------------------------------------------------------------------------------- 1 | package com.dangfm.stock.socketclient.market; 2 | 3 | import com.dangfm.stock.socketclient.Config; 4 | import com.dangfm.stock.socketclient.utils.FN; 5 | import com.dangfm.stock.socketclient.utils.FileHelper; 6 | import com.dangfm.stock.socketclient.utils.RedisCls; 7 | import com.dangfm.stock.socketclient.utils.ZipUtils; 8 | import org.json.JSONArray; 9 | import org.json.JSONException; 10 | import org.json.JSONObject; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | 14 | import java.io.*; 15 | import java.net.HttpURLConnection; 16 | import java.net.URL; 17 | import java.sql.ResultSet; 18 | import java.sql.SQLException; 19 | import java.util.Date; 20 | import java.util.Set; 21 | import java.util.zip.GZIPInputStream; 22 | 23 | /** 24 | * 采集日K 25 | * 每天凌晨和清晨采集一遍 26 | * 27 | * Created by dangfm on 16/4/20. 28 | */ 29 | public class GetStockDaysLine extends Thread{ 30 | public static final Logger logger = LoggerFactory.getLogger(GetStockDaysLine.class); 31 | // 出错等待时间 32 | private static int weittime = 10; // 10次 33 | // 超时十次跳过 34 | private static int loopTime = 0; 35 | // 保存的路径 36 | private static String klinePath = Config.klineSavePath.isEmpty()? FN.getProjectPath():Config.klineSavePath; 37 | 38 | /** 39 | * 本地redis 40 | */ 41 | private static RedisCls localRedis = new RedisCls(); 42 | private static RedisCls redis = new RedisCls(); 43 | 44 | // 是否全量更新 45 | private boolean isAll = false; 46 | 47 | // 是否全量更新 48 | private boolean isOnlyMinKline = false; 49 | 50 | private String klineserverip = null; 51 | 52 | // 是否启用压缩 1=启用 53 | private int isZip = 1; 54 | 55 | 56 | public GetStockDaysLine(boolean all){ 57 | isAll = all; 58 | } 59 | 60 | public GetStockDaysLine(boolean all,boolean _isOnlyMinKline){ 61 | isAll = all; 62 | isOnlyMinKline = _isOnlyMinKline; 63 | } 64 | 65 | @Override 66 | public void run() { 67 | super.run(); 68 | 69 | // 获取k线网关 70 | while (klineserverip==null){ 71 | klineserverip = FN.getKlineServerIp(); 72 | } 73 | 74 | if (Config.isCollectionHistoryKline) { 75 | // // 如果周六周天停止运行 76 | if (FN.getWeekOfDate(new Date(System.currentTimeMillis())).equals("6") || 77 | FN.getWeekOfDate(new Date(System.currentTimeMillis())).equals("7")) { 78 | logger.info("日k采集周六日不运行"); 79 | // 周六日全量更新 80 | isAll = true; 81 | // return; 82 | } 83 | getMarket(); 84 | }else{ 85 | logger.info("未开启采集K线开关,如需采集历史K线数据请设置配置文件 isCollectionHistoryKline=true"); 86 | } 87 | 88 | } 89 | 90 | /** 91 | * 采集日k数据入口方法 92 | * 集成采集所有沪深股市的日k数据,包括历史数据和最新数据 93 | */ 94 | public void getMarket(){ 95 | 96 | while (true) { 97 | if (Config.isCollectionHistoryKline) { 98 | // 同步k线数据 99 | if(!isOnlyMinKline) 100 | getMarket_Kline("day"); 101 | } 102 | if (Config.isCollectionHistoryMinKline) { 103 | getMarket_Kline("min1"); 104 | } 105 | try { 106 | sleep(10000); 107 | } catch (InterruptedException e) { 108 | e.printStackTrace(); 109 | } 110 | // getMarket_Kline("min5"); 111 | if (FN.isStopTime("00 9")) return; 112 | } 113 | 114 | } 115 | 116 | 117 | 118 | /** 119 | * 同步所有日K数据 包括原始数据,复权数据 120 | * @param 121 | */ 122 | public void getMarket_Kline(String cycle){ 123 | Set s = localRedis.redis(Config.redisDB_Search).keys("*"); 124 | System.out.println("开始同步原始k线"+cycle+"数据" + s.size()); 125 | Object[] list = s.toArray(); 126 | int pageSize = 100000; 127 | // 如果1分钟仅采集5天数据 128 | if(cycle.equals("min1")){ 129 | //pageSize = 240*10; 130 | } 131 | boolean isExit = false; 132 | String fileName = ""; 133 | String klineData = ""; 134 | int sleeptime = 1000; 135 | 136 | for (int i=0;i= 0) { 140 | String[] a = key.split("\\|"); 141 | //System.out.println(a[0]); 142 | if (a.length > 0) { 143 | key = a[0]; 144 | String path = klinePath + "/" + cycle + "/after/"; 145 | // 如果没开启复权采集开关,就不采集复权的数据 146 | if (!Config.isCollectionHistoryMinKline_fq && cycle.equals("min1")) { 147 | path = klinePath + "/" + cycle + "/data/"; 148 | } 149 | fileName = path + key.toUpperCase() + ".txt"; 150 | if (!isAll) { 151 | klineData = FileHelper.readToString(fileName); 152 | // 对于1分钟线来说必须大于一天的量就是240根K线才行 153 | if(cycle.equals("min1")){ 154 | if (!klineData.isEmpty()) { 155 | if (klineData.startsWith("[")) { 156 | JSONArray datas = new JSONArray(klineData); 157 | logger.info("klineData.lenght="+datas.length()); 158 | if (datas.length()<300) { 159 | klineData = ""; 160 | } 161 | }else{ 162 | klineData = ""; 163 | } 164 | } 165 | 166 | } 167 | String lastDate = ""; 168 | // 检查有没有最新的k线数据 169 | isExit = checkDataIsNewDate(klineData, key, i); 170 | 171 | if (isExit) continue; 172 | if (cycle.equals("min1")) { 173 | if (!klineData.isEmpty()) { 174 | logger.info("klineData不为空 ="+klineData.length()); 175 | pageSize = 240; 176 | } 177 | } 178 | }else{ 179 | 180 | } 181 | 182 | if (!isExit) { 183 | String params = "code=" + key + "&cycle="+cycle+"&fq=data&page=1&pageSize="+pageSize+"&zip="+isZip; 184 | long t = System.currentTimeMillis(); 185 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 186 | params = params + "&t="+t+"&app_key="+Config.appKey+"&token="+token; 187 | String url = klineserverip+Config.socketServer_kline + "?"+params; 188 | loopTime = 0; 189 | String value = getContent(url); 190 | //logger.info(url); 191 | if (!value.isEmpty()) { 192 | //System.out.println(value); 193 | // 如果是1分钟,检查拿到的是数据是否是最新日期的 194 | if (!isAll) { 195 | if (cycle.equals("min1") && !klineData.isEmpty()) { 196 | if (!checkDataIsNewDate(value, key, i)) { 197 | continue; 198 | } else { 199 | // 合并增量 200 | value = klineData.replace("]", "") + "," + value.replace("[", ""); 201 | } 202 | } 203 | } 204 | path = klinePath+"/"+cycle+"/data/"; 205 | fileName = path+key.toUpperCase()+".txt"; 206 | FileHelper.makeDirs(path); 207 | // 保存到本地 208 | if (value.length()>20) { 209 | FileHelper.createFile(fileName, value); 210 | System.out.println(i + "/" + list.length + " " + key + " k线" + cycle + "原始数据同步完成-外网" + (isAll ? "全量" : "增量")); 211 | } 212 | 213 | } 214 | 215 | sleep(sleeptime); 216 | 217 | if (Config.isCollectionHistoryMinKline_fq || cycle.equals("day")) { 218 | params = "code=" + key + "&cycle=" + cycle + "&fq=before&page=1&pageSize=" + pageSize+"&zip="+isZip; 219 | t = System.currentTimeMillis(); 220 | token = FN.MD5(params + t + Config.appKey + Config.appSecret); 221 | params = params + "&t=" + t + "&app_key=" + Config.appKey + "&token=" + token; 222 | url = klineserverip + Config.socketServer_kline + "?" + params; 223 | loopTime = 0; 224 | value = getContent(url); 225 | if (!value.isEmpty()) { 226 | if (!isAll) { 227 | // 如果是1分钟,检查拿到的是数据是否是最新日期的 228 | if (cycle.equals("min1") && !klineData.isEmpty()) { 229 | if (!checkDataIsNewDate(value, key, i)) { 230 | continue; 231 | } else { 232 | // 合并增量 233 | value = klineData.replace("]", "") + "," + value.replace("[", ""); 234 | } 235 | } 236 | } 237 | path = klinePath + "/" + cycle + "/before/"; 238 | fileName = path + key.toUpperCase() + ".txt"; 239 | FileHelper.makeDirs(path); 240 | // 保存到本地 241 | if (value.length()>20) { 242 | FileHelper.createFile(fileName, value); 243 | System.out.println(i + "/" + list.length + " " + key + " k线" + cycle + "前复权数据同步完成-外网" + (isAll ? "全量" : "增量")); 244 | } 245 | 246 | } 247 | 248 | sleep(sleeptime); 249 | 250 | params = "code=" + key + "&cycle=" + cycle + "&fq=after&page=1&pageSize=" + pageSize+"&zip="+isZip; 251 | t = System.currentTimeMillis(); 252 | token = FN.MD5(params + t + Config.appKey + Config.appSecret); 253 | params = params + "&t=" + t + "&app_key=" + Config.appKey + "&token=" + token; 254 | url = klineserverip + Config.socketServer_kline + "?" + params; 255 | loopTime = 0; 256 | value = getContent(url); 257 | if (!value.isEmpty()) { 258 | if (!isAll) { 259 | // 如果是1分钟,检查拿到的是数据是否是最新日期的 260 | if (cycle.equals("min1") && !klineData.isEmpty()) { 261 | if (!checkDataIsNewDate(value, key, i)) { 262 | continue; 263 | } else { 264 | // 合并增量 265 | value = klineData.replace("]", "") + "," + value.replace("[", ""); 266 | } 267 | } 268 | } 269 | path = klinePath + "/" + cycle + "/after/"; 270 | fileName = path + key.toUpperCase() + ".txt"; 271 | FileHelper.makeDirs(path); 272 | // 保存到本地 273 | if (value.length()>20) { 274 | FileHelper.createFile(fileName, value); 275 | System.out.println(i + "/" + list.length + " " + key + " k线" + cycle + "后复权数据同步完成-外网" + (isAll ? "全量" : "增量")); 276 | } 277 | 278 | } 279 | } 280 | value = null; 281 | } 282 | 283 | } 284 | } 285 | 286 | 287 | }catch (Exception e){ 288 | e.printStackTrace(); 289 | } 290 | 291 | try { 292 | sleep(sleeptime); 293 | } catch (InterruptedException e) { 294 | 295 | } 296 | 297 | } 298 | System.gc(); 299 | } 300 | 301 | private boolean checkDataIsNewDate(String data,String code,int i){ 302 | boolean isExit = false; 303 | // 先看看有没有最新的数据 304 | String json = redis.getValue(code); 305 | if (json!=null) { 306 | JSONObject obj = null; 307 | try { 308 | obj = new JSONObject(json); 309 | if (obj != null) { 310 | String lastDate = obj.getString("lastDate"); 311 | lastDate = lastDate.replace("-",""); 312 | // 读取股票k线所有数据 313 | // 先拿出旧的文件 314 | 315 | if (!data.isEmpty()) { 316 | if (data.startsWith("[")) { 317 | JSONArray datas = new JSONArray(data); 318 | // 查找最新K线日期 319 | int k = 0; 320 | for (int j = datas.length() - 1; j >= 0; j--) { 321 | String lineStr = datas.getString(j); 322 | if (lineStr.indexOf(",") > 0) { 323 | String[] line = lineStr.split(","); 324 | // logger.info(line); 325 | if (line.length > 0) { 326 | String lineDate = line[0]; 327 | if (!lineDate.isEmpty()) { 328 | if (Integer.parseInt(lineDate) >= Integer.parseInt(lastDate)) { 329 | // 已经有最新的K线数据了,不需要再采集 330 | System.out.println(i+"/"+code+"最新K数据已存在" + lineStr); 331 | isExit = true; 332 | break; 333 | } 334 | } 335 | } 336 | } 337 | k++; 338 | if (k > 5) break; 339 | } 340 | datas = null; 341 | } 342 | } 343 | 344 | } 345 | obj = null; 346 | }catch (JSONException e) { 347 | logger.error(e.toString()); 348 | } 349 | } 350 | json = null; 351 | return isExit; 352 | } 353 | 354 | 355 | 356 | /** 357 | * 采集K线内容回来 358 | * @param urlStr 359 | * @return 360 | */ 361 | public String getContent(String urlStr){ 362 | 363 | 364 | if(isZip==1){ 365 | return GetZipContent(urlStr); 366 | } 367 | 368 | 369 | StringBuffer sb = new StringBuffer(); 370 | try{ 371 | //logger.info("请求K线:"+urlStr+""); 372 | java.net.URL url = new java.net.URL(urlStr); 373 | BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream())); 374 | String line; 375 | while((line = in.readLine()) != null){ 376 | sb.append(line); 377 | } 378 | in.close(); 379 | 380 | if (sb.toString().startsWith("{")) { 381 | JSONObject obj = new JSONObject(sb.toString()); 382 | if (obj != null) { 383 | boolean success = obj.getBoolean("success"); 384 | if (success){ 385 | JSONArray data = obj.getJSONArray("data"); 386 | return data.toString(); 387 | }else { 388 | logger.error("请求K线出错" + obj.toString()); 389 | return ""; 390 | } 391 | }else{ 392 | logger.error("请求K线出错" + obj.toString()); 393 | return ""; 394 | } 395 | } 396 | url = null; 397 | }catch(Exception e) { 398 | // Report any errors that arise 399 | //sb.append(e.toString()); 400 | logger.error("请求K线出错"+loopTime+"次"); 401 | loopTime ++; 402 | if (loopTime10) break; 36 | try { 37 | sleep(1000); 38 | } catch (InterruptedException e) { 39 | e.printStackTrace(); 40 | } 41 | i ++; 42 | } 43 | 44 | // 获取k线网关 45 | while (klineserverip==null){ 46 | klineserverip = FN.getKlineServerIp(); 47 | } 48 | 49 | // 初始化板块 50 | initStockTypes(); 51 | // 初始化好股票 52 | initStocks(); 53 | // 初始化所有搜索库股票 54 | initSearchStocks(); 55 | // 初始化所有股票实时行情 56 | initStockRealtimeQuotes(); 57 | // 初始化财务数据 58 | initStockFinance(); 59 | // 初始化除权数据 60 | initStockExrights(); 61 | } 62 | 63 | /** 64 | * 初始化请求股票板块分类 65 | * http://kline.api.dashixiong.cn/V1/stocktypes.php 66 | */ 67 | private void initStockTypes(){ 68 | long t = System.currentTimeMillis(); 69 | String params = ""; 70 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 71 | params = params + "t="+t+"&app_key="+Config.appKey+"&token="+token; 72 | String url = klineserverip+"/stocktypes.php?"+params; 73 | // logger.info("开始初始化所有股票板块分类数据"+url); 74 | String html = HttpWebCollecter.getWebContent(url); 75 | if (html!=null){ 76 | if (!html.isEmpty()){ 77 | if (html.startsWith("{")){ 78 | try { 79 | JSONObject obj = new JSONObject(html); 80 | if (obj!=null){ 81 | JSONObject data = obj.getJSONObject("data"); 82 | if (data!=null){ 83 | JSONArray hangye = data.getJSONArray("hangye"); 84 | JSONArray gainian = data.getJSONArray("gainian"); 85 | JSONArray diqu = data.getJSONArray("diqu"); 86 | // logger.info(hangye.toString()); 87 | if (hangye!=null) { 88 | if (hangye.length() > 0) 89 | SaveAllStocks.saveAllStockType_hangye(hangye); 90 | } 91 | if (gainian!=null) { 92 | if (gainian.length() > 0) 93 | SaveAllStocks.saveAllStockType_gainian(gainian); 94 | } 95 | if (diqu!=null) { 96 | if (diqu.length() > 0) 97 | SaveAllStocks.saveAllStockType_diqu(diqu); 98 | } 99 | hangye = null; 100 | gainian = null; 101 | diqu = null; 102 | } 103 | } 104 | obj = null; 105 | } catch (JSONException e) { 106 | e.printStackTrace(); 107 | logger.error(e.toString()); 108 | } 109 | 110 | } 111 | } 112 | } 113 | html = null; 114 | logger.info("初始化所有股票板块分类数据-完成,用时:"+(System.currentTimeMillis()-t)+"ms"); 115 | } 116 | 117 | /** 118 | * 初始化请求股票数据 119 | * http://kline.api.dashixiong.cn/V1/stocktypes.php 120 | */ 121 | private void initStocks(){ 122 | long t = System.currentTimeMillis(); 123 | String params = ""; 124 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 125 | params = params + "t="+t+"&app_key="+Config.appKey+"&token="+token; 126 | String url = klineserverip+"/stocks.php?"+params; 127 | // logger.info("开始初始化所有股票数据"+url); 128 | String html = HttpWebCollecter.getWebContent(url); 129 | if (html!=null){ 130 | if (!html.isEmpty()){ 131 | if (html.startsWith("{")){ 132 | try { 133 | JSONObject obj = new JSONObject(html); 134 | if (obj!=null){ 135 | JSONArray data = obj.getJSONArray("data"); 136 | if (data!=null){ 137 | for (int i = 0; i < data.length(); i++) { 138 | String rows = data.getString(i); 139 | String key = rows; 140 | if (rows.indexOf(":tree:")>0){ 141 | String[] a = rows.split(":tree:"); 142 | if (a.length>0){ 143 | String code = a[0]; 144 | rows = a[1]; 145 | if (rows.indexOf("typeIds:")>0){ 146 | a = rows.split("typeIds:"); 147 | if (a.length>0){ 148 | String tree = a[0]; 149 | String typeIds = a[1]; 150 | String type = "0"; 151 | if (code.startsWith("sh000") || code.startsWith("sz399")){ 152 | type = "1"; 153 | } 154 | 155 | // sh600169:tree:0,666666 typeIds:,666666,6,67,130,192,201,2... ; 156 | JSONObject item = new JSONObject(); 157 | item.put("code",code); 158 | item.put("typeTree",tree); 159 | item.put("typeIds",typeIds); 160 | item.put("type",type); 161 | item.put("isStop","0"); 162 | String value = item.toString(); 163 | item = null; 164 | 165 | Set ss = redisCls.redis(Config.redisDB_stocks).keys(code + "*"); 166 | if (ss.size() > 0) { 167 | Object[] lists = ss.toArray(); 168 | for (int j = 0; j < lists.length; j++) { 169 | // 这样可以避免中文名称不同而重复 170 | String keys = (String) lists[j]; 171 | redisCls.redis(Config.redisDB_stocks).del(keys); 172 | keys = null; 173 | } 174 | lists = null; 175 | } 176 | redisCls.redis(Config.redisDB_stocks).set(key,value); 177 | 178 | ss = null; 179 | item = null; 180 | 181 | 182 | } 183 | } 184 | } 185 | } 186 | } 187 | } 188 | data = null; 189 | 190 | } 191 | obj = null; 192 | } catch (JSONException e) { 193 | e.printStackTrace(); 194 | logger.error(e.toString()); 195 | } 196 | 197 | } 198 | } 199 | } 200 | html = null; 201 | logger.info("初始化所有股票数据-完成,用时:"+(System.currentTimeMillis()-t)+"ms"); 202 | } 203 | 204 | /** 205 | * 初始化请求股票搜索库数据 206 | * http://kline.api.dashixiong.cn/V1/search.php 207 | */ 208 | private void initSearchStocks(){ 209 | long t = System.currentTimeMillis(); 210 | String params = ""; 211 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 212 | params = params + "t="+t+"&app_key="+Config.appKey+"&token="+token; 213 | String url = klineserverip+"/search.php?"+params; 214 | // logger.info("开始初始化所有股票搜索库数据"+url); 215 | String html = HttpWebCollecter.getWebContent(url); 216 | if (html!=null){ 217 | if (!html.isEmpty()){ 218 | if (html.startsWith("{")){ 219 | try { 220 | JSONObject obj = new JSONObject(html); 221 | if (obj!=null){ 222 | JSONArray data = obj.getJSONArray("data"); 223 | if (data!=null){ 224 | for (int i = 0; i < data.length(); i++) { 225 | String rows = data.getString(i); 226 | 227 | if (rows.indexOf("|")>0) { 228 | // logger.info(rows); 229 | String[] a = rows.split("\\|"); 230 | String code = a[0]; 231 | if (code.startsWith("sh") || code.startsWith("sz")) { 232 | Set ss = redisCls.redis(Config.redisDB_Search).keys(code + "*"); 233 | if (ss.size() > 0) { 234 | Object[] lists = ss.toArray(); 235 | for (int j = 0; j < lists.length; j++) { 236 | // 这样可以避免中文名称不同而重复 237 | String keys = (String) lists[j]; 238 | redisCls.redis(Config.redisDB_Search).del(keys); 239 | keys = null; 240 | } 241 | lists = null; 242 | } 243 | redisCls.redis(Config.redisDB_Search).set(rows, rows); 244 | ss = null; 245 | } 246 | } 247 | rows = null; 248 | } 249 | } 250 | data = null; 251 | } 252 | obj = null; 253 | } catch (JSONException e) { 254 | e.printStackTrace(); 255 | logger.error(e.toString()); 256 | } 257 | 258 | } 259 | } 260 | } 261 | html = null; 262 | logger.info("初始化所有股票搜索库数据-完成,用时:"+(System.currentTimeMillis()-t)+"ms"); 263 | } 264 | 265 | /** 266 | * 初始化请求股票实时行情数据 267 | * http://kline.api.dashixiong.cn/V1/search.php 268 | */ 269 | private void initStockRealtimeQuotes(){ 270 | long t = System.currentTimeMillis(); 271 | String params = ""; 272 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 273 | params = params + "t="+t+"&app_key="+Config.appKey+"&token="+token; 274 | String url = klineserverip+"/allstockquotes.php?"+params; 275 | // logger.info("开始初始化所有股票搜索库数据"+url); 276 | String html = HttpWebCollecter.getWebContent(url); 277 | if (html!=null){ 278 | if (!html.isEmpty()){ 279 | if (html.startsWith("{")){ 280 | try { 281 | JSONObject obj = new JSONObject(html); 282 | if (obj!=null){ 283 | JSONObject data = obj.getJSONObject("data"); 284 | if (data!=null){ 285 | String names = data.getString("names"); 286 | names = names.replace("[",""); 287 | names = names.replace("]",""); 288 | JSONArray namekeys = new JSONArray("["+names+"]"); 289 | JSONArray datas = data.getJSONArray("datas"); 290 | for (int i = 0; i < datas.length(); i++) { 291 | String jsonStr = datas.getString(i); 292 | // logger.debug(jsonStr); 293 | JSONObject shObj = FN.stoObj(jsonStr, namekeys); 294 | if (shObj.length()>0) { 295 | /** 296 | * 这里写入redis 297 | */ 298 | if(shObj.has("code")) { 299 | String code = shObj.getString("code"); 300 | if (code.startsWith("sh") || code.startsWith("sz")) { 301 | localRedis.setValue(code, shObj.toString()); 302 | } 303 | 304 | } 305 | } 306 | shObj = null; 307 | jsonStr = null; 308 | } 309 | namekeys = null; 310 | names = null; 311 | } 312 | data = null; 313 | } 314 | obj = null; 315 | } catch (JSONException e) { 316 | e.printStackTrace(); 317 | logger.error(e.toString()); 318 | } 319 | 320 | } 321 | } 322 | } 323 | html = null; 324 | logger.info("初始化所有股票实时行情数据-完成,用时:"+(System.currentTimeMillis()-t)+"ms"); 325 | } 326 | 327 | /** 328 | * 初始化请求股票除权数据 329 | * http://kline.api.dashixiong.cn/V1/exrights.php 330 | */ 331 | private void initStockExrights(){ 332 | 333 | long t = System.currentTimeMillis(); 334 | String params = ""; 335 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 336 | params = params + "t="+t+"&app_key="+Config.appKey+"&token="+token; 337 | String url = klineserverip+"/exrights.php?"+params; 338 | // logger.info("开始初始化所有股票搜索库数据"+url); 339 | String html = HttpWebCollecter.getWebContent(url); 340 | if (html!=null){ 341 | if (!html.isEmpty()){ 342 | if (html.startsWith("{")){ 343 | try { 344 | JSONObject obj = new JSONObject(html); 345 | if (obj!=null){ 346 | JSONObject data = obj.getJSONObject("data"); 347 | if (data!=null){ 348 | JSONArray keys = data.names(); 349 | for (int i = 0; i < keys.length(); i++) { 350 | String key = keys.getString(i); 351 | String value = data.getString(key); 352 | if (value.length()>0) { 353 | /** 354 | * 这里写入redis 355 | */ 356 | exRedis.redis(Config.redisDB_upDown).hset(Config.redisKey_exright_tables,key,value); 357 | } 358 | value = null; 359 | key = null; 360 | } 361 | keys = null; 362 | } 363 | data = null; 364 | } 365 | obj = null; 366 | } catch (JSONException e) { 367 | e.printStackTrace(); 368 | logger.error(e.toString()); 369 | } 370 | 371 | } 372 | } 373 | } 374 | html = null; 375 | logger.info("初始化所有股票除权数据-完成,用时:"+(System.currentTimeMillis()-t)+"ms"); 376 | } 377 | 378 | /** 379 | * 初始化请求股票财务数据 380 | * http://kline.api.dashixiong.cn/V1/finance.php 381 | */ 382 | private void initStockFinance(){ 383 | 384 | long t = System.currentTimeMillis(); 385 | String params = ""; 386 | String token = FN.MD5(params+t+Config.appKey+Config.appSecret); 387 | params = params + "t="+t+"&app_key="+Config.appKey+"&token="+token; 388 | String url = klineserverip+"/finance.php?"+params; 389 | // logger.info("开始初始化所有股票搜索库数据"+url); 390 | String html = HttpWebCollecter.getWebContent(url); 391 | if (html!=null){ 392 | if (!html.isEmpty()){ 393 | if (html.startsWith("{")){ 394 | try { 395 | JSONObject obj = new JSONObject(html); 396 | if (obj!=null){ 397 | JSONObject data = obj.getJSONObject("data"); 398 | if (data!=null){ 399 | JSONArray keys = data.names(); 400 | for (int i = 0; i < keys.length(); i++) { 401 | String key = keys.getString(i); 402 | String value = data.getString(key); 403 | if (value.length()>0) { 404 | /** 405 | * 这里写入redis 406 | */ 407 | exRedis.redis(Config.redisDB_upDown).hset(Config.redisKey_financial_tables,key,value); 408 | } 409 | value = null; 410 | key = null; 411 | } 412 | keys = null; 413 | } 414 | data = null; 415 | } 416 | obj = null; 417 | } catch (JSONException e) { 418 | e.printStackTrace(); 419 | logger.error(e.toString()); 420 | } 421 | 422 | } 423 | } 424 | } 425 | html = null; 426 | logger.info("初始化所有股票财务数据-完成,用时:"+(System.currentTimeMillis()-t)+"ms"); 427 | } 428 | } 429 | 430 | 431 | --------------------------------------------------------------------------------