手写弹幕服务器—包看懂篇
手写弹幕服务器—包看懂篇
socket.io
简介
使用流行的 web 应用技术栈 —— 比如 LAMP (PHP) —— 来编写聊天应用通常是很困难的。它包含了轮询服务器以检测变化,还要追踪时间戳,并且这种实现是比较慢的。
大多数实时聊天系统通常基于 socket 来构建。 Socket 为客户端和服务器提供了双向通信机制。
这意味着服务器可以 推送 消息给客户端。无论何时你发布一条消息,服务器都可以接收到消息并推送给其他连接到服务器的客户端。
web 框架
首先要制作一个 HTML 页面来提供表单和消息列表。我们使用了基于 Node.JS 的 web 框架 express 。 请确保安装了 Node.JS。
首先创建一个 package.json 来描述我们的项目。 推荐新建一个空目录 (这里使用 chat-example)。
express 已经安装好了。我们现在新建一个 index.js 文件来创建应用。
var app = require('express')();
var http = require('http').Server(app);
app.get('/', function(req, res){
res.send('Hello world ');
});
http.listen(3000, function(){
console.log('listening on *:4000');
});
这段代码作用如下:
Express 初始化 app 作为 HTTP 服务器的回调函数。
定义了一个路由 / 来处理首页访问。
使 http 服务器监听端口 4000。
HTML 服务器
目前在 index.js 中我们是通过 res.send 返回一个 HTML 字符串。 如果我们将整个应用的 HTML 代码都放到应用代码里,代码结构将变得很混乱。 替代的方法是新建一个 index.html 文件作为服务器响应。
现在我们用 sendFile 来重构之前的回调:
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
index.html 内容如下:
Socket.IO chat
集成 Socket.IO
Socket.IO 由两部分组成:
一个服务端用于集成 (或挂载) 到 Node.JS HTTP 服务器: socket.io
一个加载到浏览器中的客户端: socket.io-client
这个两部分都会运用到
npm install --save socket.io
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
console.log('a user connected');
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
我们通过传入 http (HTTP 服务器) 对象初始化了 socket.io 的一个实例。 然后监听 connection 事件来接收 sockets, 并将连接信息打印到控制台。
在 index.html 的
标签中添加如下内容:
这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。
请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。
重新加载服务器和网站,你将看到控制台打印出 “a user connected”。
每个 socket 还会触发一个特殊的 disconnect 事件:
io.on('connection', function(socket){
console.log('a user connected');
socket.on('disconnect', function(){
console.log('user disconnected');
});
});
触发事件
Socket.IO 的核心理念就是允许发送、接收任意事件和任意数据。任意能被编码为 JSON 的对象都可以用于传输。二进制数据 也是支持的。
这里的实现方案是,当用户输入消息时,服务器接收一个 chat message 事件。index.html 文件中的 script 部分现在应该内容如下:
广播
接下来的目标就是让服务器将消息发送给其他用户。
要将事件发送给每个用户,Socket.IO 提供了 io.emit 方法:
io.emit('some event', { for: 'everyone' });
为了简单起见,我们将消息发送给所有用户,包括发送者。
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
用法总结
服务端
io.on('connection',function(socket));
监听客户端连接,回调函数会传递本次连接的socket
io.sockets.emit('String',data);
给所有客户端广播消息
socket.broadcast.emit("msg",{data:"hello,everyone"});
给除了自己以外的客户端广播消息
io.sockets.socket(socketid).emit('String', data);
给指定的客户端发送消息
socket.on('String',function(data));
监听客户端发送的信息
socket.emit('String', data);
给该socket的客户端发送消息
io.of('/some').on('connection', function (socket) {
socket.on('test', function (data) {
socket.broadcast.emit('event_name',{});
});
});
分组
进阶——处理用户发送的数据
一、redis
什么是Redis?
REmote DIctionary Server(Redis) 是一个由SalvatoreSanfilippo写的key-value(键值对)存储系统。
Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
它通常被称为数据结构服务器,因为值(value)可以是字符串(String), 哈希(Map), 列表(list), 集合(sets) 和有序集合(sorted sets)等类型。
Redis中的数据类型
哈希(Map hashmap):散列表(Hash table,也叫哈希表),是根据键(Key)而直接访问在内存存储位置的数据结构。
列表(list):列表是一种数据项构成的有限序列,即按照一定的线性顺序,排列而成的数据项的集合。(redis中使用双向链表实现)
集合(sets):和中学时学习的概念是相似的。特点是集合中元素不能重复是唯一的。切内部是无序的
有序集合(sorted sets):也是一种集合,但是内部数据是经过排序的。
redis安装
Redis 安装链接
npm redis
redis使用方法
0、建立node-redis的client端连接 npm i redis --save
// redis 链接
var redis = require('redis');
var client = redis.createClient('6379', '127.0.0.1');
// redis 链接错误
client.on("error", function(error) {
console.log(error);
});
// redis 验证 (reids.conf未开启验证,此项可不需要)
// client.auth("foobared");
module.exports = {
client:client
}
1、set的存取
const {client} = require('./redis')
client.set('key001', 'AAA', function (err, response) {
if (err) {
console.log("err:", err);
} else {
console.log(response);
client.get('key001', function (err, res) {
if (err) {
console.log("err:", err);
} else {
console.log(res);
client.end(true);
}
});
}
});
2、hash存取
hash set的设值和抽取数据都有单个key和多个key两种方式:
const {client} = require('./redis')
client.hset('filed002', 'key001', 'wherethersisadoor', function (err, res) {
if (err) {
console.log(err);
} else {
console.log('res:', res);
client.hget('filed002', 'key001', function (err, getRslt) {
if (err) {
console.log(err);
} else {
console.log('getRslt:', getRslt);
client.end(true);
}
});
}
});
注意:当hget方法在指定field下找不到指定的key时,会传给回调函数null,而非空字符或undefined。
※ 设定多个key的值,取值时获取指定field下指定单个或多个key的值
const {client} = require('./redis')
var qe = {a: 2, b:3, c:4};
client.hmset('field003', qe, function(err, response) {
console.log("err:", err);
console.log("response:", response);
client.hmget('field003', ['a', 'c'], function (err, res) {
console.log(err);
console.log(res);
client.end(true);
});
});
hmset方法的设定值可以是JSON格式的数据,但是redis中key的值是以字符串形式存储的,如果JSON数据层数超过一层,会出现值是'[object Object]'的情况。
hmget方法的返回值是个数组,其中元素的顺序对应于参数的key数组中的顺序,如果参数数组中有在field内不存在的key,返回结果数组的对应位置会是null,也即无论是否能取到值,结果数组中的元素位置始终与参数的key数组中元素位置一一对应。
获取hash中所有key的方法是client.keys(fieldname, callback); 需要注意的是如果hash中key的数目很多,这个方法的可能耗费很长时间。
3.链表 适合存储社交网站的新鲜事 lpush key value [value ...] 向链表key左边添加元素 rpush key value [value...] 向链表key右边添加元素 lpop key 移除key链表左边第一个元素 rpop key 移除key链表右边第一元素
const {client} = require('./redis')
client.lpush('test', 12345, function(err, response) {
if(err){
console.log("err:", err);
}else{
console.log("response:", response);
client.rpop('test',function (err, res){
if(err){
console.log(err);
}else{
console.log(res);
client.end(true);
}
});
}
});
[图片上传失败...(image-354cf6-1519888571721)]
socket.io中接入redis 并创建多个命名空间
How to use
const io = require('socket.io')(3000);
const redis = require('socket.io-redis');
io.adapter(redis({ host: 'localhost', port: 6379 }));
将index.js修改为
const app = require('express')();
const http = require('http').Server(app);
const io = require('socket.io')(http);
const redis = require('socket.io-redis');
const {client} = require('./test/redis')
const moment = require('moment')
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.adapter(redis({host: 'localhost', port: 6379}));
var nameBox = ['/chatroom','/live','/vod','/wechat','/broadcast'];
for(var item in nameBox){
var nsp = io.of(nameBox[item])
socketMain(nsp,nameBox[item])
}
function socketMain(nsp,roomName) {
nsp.on('connection',function (socket) {
console.log('a user connected')
socket.on('disconnect', function(){
console.log('user disconnected');
});
socket.on('chat message', function(msg){
var data = {"socketid":socket.id,"cid":roomName,"msg":msg,createTime:moment().unix()};
client.lpush('message',JSON.stringify(data),redis.print)
console.log('message: ' + msg);
});
})
}
http.listen(4000, function(){
console.log('listening on *:4000');
});
index.html
var socket = io.connect("http://127.0.0.1:4000/live");
接入redis
client.lpush('message',JSON.stringify(msg),redis.print)
二、另起一个服务端拿redis数据进行处理
修改redis.js
module.exports = {
client:client,
ip:'http://127.0.0.1:4000'
}
新建sclient.js
const io = require('socket.io-client');
const async = require('async');
const moment = require('moment');
const redis = require('redis');
const {client,ip} = require('./test/redis');
const domain = require('domain');
const debug = require('debug')('socket-client:main');
var origin = io.connect(ip+'/', {reconnect: true});
var chatroom = io.connect(ip+'/chatroom', {reconnect: true});
var live = io.connect(ip+'/live', {reconnect: true});
var vod = io.connect(ip+'/vod', {reconnect: true});
var wechat = io.connect(ip+'/wechat', {reconnect: true});
var broadcast = io.connect(ip+'/broadcast', {reconnect: true});
var namBox = {root:origin,chatroom:chatroom,live:live,vod:vod,wechat:wechat,broadcast:broadcast};
var reqDomain = domain.create();
reqDomain.on('error', function (err) {
console.log(err);
try {
var killTimer = setTimeout(function () {
process.exit(1);
}, 100);
killTimer.unref();
} catch (e) {
console.log('error when exit', e.stack);
}
});
reqDomain.run(function () {
compute();
});
process.on('uncaughtException', function (err) {
console.log(err);
try {
var killTimer = setTimeout(function () {
process.exit(1);
}, 100);
killTimer.unref();
} catch (e) {
console.log('error when exit', e.stack);
}
});
function compute() {
client.llen('message', function(error, count){
if(error){
console.log(error);
}else{
if(count){
//console.log('-------------has count',time);
popLogs();
process.nextTick(compute);
}else{
//console.log('-------------empty',time);
setTimeout(function(){
compute();
},100);
}
}
});
}
function popLogs(){
var time = moment().unix();
console.log('-------------dealStart-------------',time);
client.rpop('message',function(err,result){
if(err){
console.log(err);
}else{
var result = JSON.parse(result);
try{
var cid = result.cid;
//console.log('place',result.place);
}catch(e){
console.log('empty data cid',result);
return;
}
console.log(' start '+' nsp: '+cid +' time: '+time);
if(namBox[cid]){
console.log(result);
namBox[cid].emit('redisCome',result);
}
}
});
}
修改index.js 增加redisCome监听事件
/*接收redis发来的消息*/
socket.on('redisCome',function (data) {
console.log('-------------redisCome',data.msg);
try{
var msg = data.msg
}catch(e){
var msg = '';
}
console.log(data);
nsp.emit('message.add',msg);
});
修改index.html
socket.on('message.add',function (msg) {
$('#messages').append($('').text(msg));
})
三、增加用户发送信息校验
增加信息的安全性,我们可以对用户发送的信息进行敏感词、sql注入攻击、xss攻击等进行过滤 使用async一步步操作流程
修改sclient.js
async.waterfall([
function (done) {
user.messageDirty({msg:result.msg},function(err,res){
//console.log('sql done'/*,res*/);
done(err,res);
});
},
function (res,done) {
user.messageValidate({msg:result.msg},function(err,res){
//console.log('key done'/*,res*/);
done(err,res);
});
}
],function (err,res) {
if(err){
console.log('err!!!!',err,result);
namBox[cid].emit('messageError',err);
}else{
if(namBox[cid]) {
console.log(result);
namBox[cid].emit('redisCome', result);
}
}
})
修改index.js
/*接收redis错误信息返回*/
socket.on('messageError',function(err){
console.log('messageError');
try{
nsp.emit('message.error',err.msg);
}catch(e){
}
});
修改index.html
mysql入库
1.在本地安装mysql数据库 2.下载node mysql包
npm install mysql --save
3.连接数据库 建立连接池
var mysql = require('mysql');
var pool = mysql.createPool({
host: 'localhost',
user:'root',
password:'123456',
database : 'danmaku'
});
var query = function(sql,options,callback){
pool.getConnection(function(err,conn){
if(err){
callback(err,null,null);
}else{
conn.query(sql,options,function(err,results,fields){
//释放连接
conn.release();
//事件驱动回调
callback(err,results,fields);
});
}
});
};
新建query.js
var {query} = require("./test/redis");
query("select * from demo", function(err,results,fields){
//do something
if(err){
console.log(err)
}else {
console.log(results)
}
});
新建insert.js
var {query} = require("./test/redis");
const moment = require('moment')
query('insert into demo(message,createTime) values(?,?)',[123,moment().unix()],function(err,results,fields){
//do something
if(err){
console.log(err)
}else {
console.log(results)
}
});
mysql -u root -p use danmaku; select * from demo;
4.在程序中添加入库步骤
弹幕播放器
ABPlayerHTML5
你可能感兴趣的:(手写弹幕服务器—包看懂篇)
C#实现高性能异步文件下载器(支持进度显示/断点续传)
WangMing_X
C#实现各种功能工具集 c# 开发语言 异步下载
一、应用场景分析异步文件下载器用处很大,当我们需要实现以下功能时可以用的上:大文件下载(如4K视频/安装包)避免UI线程阻塞,保证界面流畅响应多任务并行下载支持同时下载多个文件,提升带宽利用率后台静默下载结合Windows服务实现应用自动更新断点续传系统网络中断后可恢复下载(扩展实现)二、技术实现方案核心组件选择方案优点缺点WebClient代码简洁无法精细控制下载过程HttpWebRequest
Java jar包后台运行方式详解
我真的不想做程序员
java java jar 后端 开发语言 ide
目录一、打包成jar文件二、后台运行jar文件三、示例四、总结在Java开发中,我们经常需要将应用程序打包成可执行的jar文件,并在后台运行。这种方式对于部署长时间运行的任务或需要持续监听事件的应用程序非常重要。本文将详细介绍如何实现Javajar包的后台运行,并通过具体代码示例帮助您更好地理解和应用。一、打包成jar文件要将Java应用程序打包成jar文件,首先需要确保项目的目录结构符合要求。一
600条最强 Linux 命令总结(非常详细)零基础入门到精通,收藏这一篇就够了
网安导师小李
程序员 编程 网络安全 linux 运维 服务器 学习 web安全 python java
一、基本命令uname-m显示机器的处理器架构uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部件(SMBIOS/DMI)hdparm-i/dev/hda罗列一个磁盘的架构特性hdparm-tT/dev/sda在磁盘上执行测试性读取操作系统信息arch显示机器的处理器架构uname-m显示机器的处理器架构uname-r显示正在使用的内核版本dmidecode-q显示硬件系统部
MySQL保姆级教程(SQL语法基础篇)从小白到高手的进阶指南,收藏这一篇就够了
网安导师小李
网络安全 编程 程序员 mysql sql adb 安全 web安全 网络 自动化
本章节精心构构造SQL语法学习之旅的基石,旨在从基础出发,逐步深入,全面解析SQL语法规则并辅以丰富实例。通过这一篇章,您将循序渐进地掌握MySQL的核心语法,开启数据库操作的新境界。1:SQL语言概述SQL(StructuredQueryLanguage),简称SQL。结构化查询语言包含6个部分:类型释义范例数据查询语言DQL:DataQueryLanguage如SELECT数据操作语言DML:
【C#实现手写Ollama服务交互,实现本地模型对话】
吾与谁归in
C#学习 WPF c# Ollama Deepseek 本地模型
前言C#手写Ollama服务交互,实现本地模型对话最近使用C#调用OllamaSharpe库实现Ollama本地对话,然后思考着能否自己实现这个功能。经过一番查找,和查看OllamaSharpe源码发现确实可以。其实就是开启Ollama服务后,发送HTTP请求,获取返回结果以及一些数据处理。基本流程1、启动Ollama服务进程。2、创建HttpClient对象。3、创建请求体(参数:模型名称、提示
《 C++ 点滴漫谈: 三十 》高手写 C++,参数这样传才高效!你真的用对了吗?
Lenyiin
编程显微镜 c++ 函数参数 值传递 引用传递 指针传递 可变参数 完美转发
摘要C++函数参数的传递方式直接影响代码的性能与可读性。在本篇博客中,我们全面探讨了C++的各种参数传递方式,包括值传递、引用传递、指针传递等,并深入解析了**constexpr、consteval、std::forward、完美转发、auto模板推导等现代C++特性。此外,我们总结了不同场景下的最佳实践**,帮助开发者在实际编程中做出最优选择,提升代码质量与执行效率。无论是初学者还是有经验的C+
Android SDK 环境配置与离线安装问题(校园网)
xdjkyb
Android android c google microsoft dataset 短网址服务
一、SDK环境配置过程出现的问题:FailedtofetchURLhttp://dl-ssl.google.com/android/repository/addons_list.xml,reason:Filenotfound.这是国内网络和谐掉了google服务器,解决办法:找到c:\windows\system32\drivers\etc下的HOST文件,将:74.125.237.1dl-ssl
搭建分布式Hive集群
逸曦玥泱
大数据运维 分布式 hive hadoop
title:搭建分布式Hive集群date:2024-11-2923:39:00categories:-服务器tags:-Hive-大数据搭建分布式Hive集群本次实验环境:Centos7-2009、Hadoop-3.1.4、JDK8、Zookeeper-3.6.3、Mysql-5.7.38、Hive-3.1.2功能规划方案一(本地运行模式)Master主节点(Mysql+Hive)192.168
【新手向】从零开始学习Java(Day29)Java 网络编程
星河天欲瞩
从零开始学习Java 学习 java 开发语言 jvm 网络 后端
每天二十分钟,成就Java大神,点点关注不迷路!今天是第二十九天,给坚持到这里的小伙伴点个赞!对抗混乱即修行,共勉!目录网络编程基础概念Socket(套接字)ServerSocket类(服务器端)构造方法常用方法Socket类构造方法常用方法InetAddress类本地实例服务端客户端运行步骤下节预告网络编程基础概念网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来。网络模
ESP32 小智 AI 机器人入门教程从原理到实现(自己云端部署)
与光同尘 大道至简
人工智能 机器人 python 人机交互 github visual studio 单片机
此博客为一篇针对初学者的详细教程,涵盖小智AI机器人的原理、硬件准备、软件环境搭建、代码实现、云端部署以及优化扩展。文章结合了现有的网络资源,取长补短,确保内容易于理解和操作。简介:本教程将指导初学者使用ESP32微控制器开发一个简单的语音对话机器人“小智”。我们将介绍所需的基础原理、硬件准备、软件环境搭建,以及如何编写代码实现语音唤醒和与云端大模型的对接。通过本教程,即使没有深厚的AI或嵌入式经
Shodan的概述与安装
耶耶Norsea
Shodan 安全 web安全 python
一、Shodan简述Shodan是一个独特的网络搜索引擎,它专门针对互联网上的设备进行不间断扫描,并将扫描结果存储起来,供用户检索。这使得Shodan能够快速搜索到网络中的各种设备和服务,例如Web服务器、路由器、摄像头、物联网设备等,甚至包括某些已知漏洞的暴露设备。Shodan的主要用途:设备搜索:通过Shodan,你可以搜索到全球范围内连接到互联网的各种设备,如企业服务器、摄像头、智能家居设备
深入学习Nginx:从入门到实践
小码快撩
nginx 学习 运维
引言Nginx,全名“EngineX”,是一款高性能的HTTP和反向代理服务器,由俄罗斯程序员IgorSysoev开发。以其轻量级、高并发处理能力和稳定性而闻名于世,广泛应用于负载均衡、动静内容分离、API网关、缓存服务以及静态文件服务等多个场景。本文旨在为读者提供一份详尽的Nginx技术学习指南,助您快速掌握并应用这一强大工具。。一、事件驱动模型在Nginx中,事件驱动模型是其高效处理并发连接的
云原生Serverless平台:无服务器计算的架构革命
桂月二二
云原生 serverless 架构
引言:从虚拟机到函数即服务(FaaS)AWSLambda每天处理数十万亿次请求,阿里巴巴函数计算支撑双十一亿级事件触发。KnativeServing实现秒级自动扩缩至零,Vercel边缘函数网络响应时间跌破50ms。CNCFOpenFaaS在GitHub斩获25k星,AzureFunctions支持毫秒级计费精度,GoogleCloudRun冷启动优化至200ms内。全球500强企业70%采用Se
RuoYi-Vue部署到Linux服务器(Jar+Nginx)
pingcode
若依框架 JAVA全栈开发笔记(全) JAVA运维笔记 ruoyi
一、本地环境准备源码下载、本地Jdk及Node.js环境安装,参考以下文章。附:RuoYi-Vue下载与运行二、服务器环境准备1.安装Jdk附:JDK8下载安装与配置环境变量(linux)2.安装MySQL附:MySQL8免安装版下载安装与配置(linux)3.安装Redis附:Redis下载安装与配置(linux)4.安装Nginx附:
TTP/HTTPS、TCP/IP 协议、RPC、Socket 通信机制
种豆走天下
https tcp/ip rpc
1.TTP/HTTPSTTP(HTTP)和HTTPS(HypertextTransferProtocolSecure)是基于TCP/IP协议的应用层协议,主要用于客户端和服务器之间的数据传输。HTTP(超文本传输协议):这是用于web页面和服务器之间通信的标准协议。它是无状态的、无连接的协议,数据是以纯文本形式传输的。HTTPS(超文本传输安全协议):它是HTTP协议的安全版本,通过SSL/TLS
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12
宝码香车
# DeepSeek javascript 前端 vue.js ecmascript DeepSeek
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏+关注哦目录DeepSeek助力Vue3开发:打造丝滑的表格(Table)之功能优化,添加列宽调整功能Table12页面效果指令输入think组件代码功能增强说明:注意事项:代码测试测试代码正常跑通,附其他基本代码编写路由src\router\index
Python __init__.py
愚昧之山绝望之谷开悟之坡
python init
Python__init__.py作用详解尼古拉苏关注12018.06.1012:57:34字数745阅读45,278转载于:https://www.cnblogs.com/tp1226/p/8453854.html__init__.py该文件的作用就是相当于把自身整个文件夹当作一个包来管理,每当有外部import的时候,就会自动执行里面的函数。1.标识该目录是一个python的模块包(modul
centos7使用yum网络安装
CentOS7Yum网络安装完全指南核心原理分析Yum(YellowdogUpdater,Modified)作为RPM系统的智能化软件包管理工具,通过以下机制实现自动化安装:依赖解析:自动识别软件包的前置依赖关系仓库同步:连接配置的软件仓库(repo)获取元数据事务处理:采用原子化操作保证安装/更新的完整性️全流程安装步骤详解步骤1:连接CentOS7服务器sshusername@server-i
ToughRADIUS 快速安装指南 - 搭建开源用户认证
运维
ToughRADIUS快速安装指南ToughRADIUS是一种健壮、高性能、易于扩展的开源RADIUS服务器。本指南将引导您快速地在您的系统上安装和配置ToughRADIUS服务。当前版本是基于Go语言开发的。开源项目地址:https://github.com/talkincode/toughradius官方文档:https://www.toughradius.net/docs/documents
ELK Stack 安装教程 - 构建日志存储告警系统
运维
介绍“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash和Kibana。Elasticsearch是一个搜索和分析引擎。Logstash是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如Elasticsearch等“存储库”中。Kibana则可以让用户在Elasticsearch中使用图形和图表对数据进行可视化。目前最
Zookeeper学习
种豆走天下
zookeeper 学习 分布式
Zookeeper是一个开源的分布式协调框架,它主要用于处理分布式系统中的一些常见问题,如同步、配置管理、命名服务和集群管理等。Zookeeper是由Apache提供的,并且广泛应用于各种分布式应用中,特别是在高可用、高可靠性和高性能的系统中。Zookeeper的主要功能分布式协调:Zookeeper提供了协调多个节点(服务器)间行为的机制。例如,分布式锁、选举、配置管理等。命名服务:Zookee
.NET 6 WebApi使用JWT
wenqi.xu
.net .netcore
JWT(JsonWebToken)jwt是一种用于身份验证的开放标准,他可以在网络之间传递信息,jwt由三部分组成:头部,载荷,签名。头部包含了令牌的类型和加密算法,载荷包含了用户的信息,签名则是对头部和载荷的加密结果。jwt鉴权验证是指在用户登录成功后,服务器生成一个jwt令牌并返回给客户端,客户端在后续的请求中携带该令牌,服务通过令牌的签名来确定用户的身份和权限。这种方式可以避免在每个请求中都
在linux下安装GCC报依赖关系错误问题
肅
linux 运维 java 服务器
在linux下安装GCC报依赖关系错误问题解决办法:背景:公司给的机器,机器是禁网的情况下。挂载了镜像安装,但在安装Redis的时候显示没有安装gcc,再安装gcc的时候提示机子上的glibc跟挂载镜像里面的不匹配,系统中已安装的glibc版本为2.17-326.el7_9,安装源中提供的gcc软件包要求使用的glibc版本为2.17-317.el7。所以依赖出了问题[root@localhost
有趣的学习Python-第十篇:Python的“魔法宝库”:标准库之旅
王盼达
有趣的学习Python 学习 python 开发语言
Python不仅是一门强大的编程语言,更像是一座充满宝藏的“魔法宝库”,里面装满了各种各样的“魔法工具”(标准库)。这些“魔法工具”可以帮助你轻松地完成各种任务,从文件操作到网络编程,从数据处理到性能优化。接下来,让我们一起探索Python的“魔法宝库”,看看这些“魔法工具”到底有多神奇!10.1操作系统接口:与“魔法世界”互动os模块就像是一个“魔法接口”,可以帮助你与操作系统进行互动。你可以用
有趣的学习Python-第八篇:Python的“魔法盾牌”:错误与异常处理
王盼达
有趣的学习Python 学习 python 开发语言
在Python的魔法世界里,即使是经验丰富的魔法师也可能遇到一些“魔法失误”。这些失误分为两种:语法错误和异常。别担心,Python为你准备了一面强大的“魔法盾牌”,帮助你应对这些挑战。8.1语法错误:魔法咒语写错了语法错误就像是你在念魔法咒语时,不小心说错了单词。这是学习Python过程中最常见的问题。比如,你可能忘记在while循环后面加上冒号:whileTrueprint('Hellowor
OpenGL疑惑
阳光开朗_大男孩儿
OpenGL 算法 c++ qt OpenGL
本篇文章基于完整例子和调用关系qtOpenGL-CSDN博客进行的疑惑补充,建议先观看例子,在看此篇。1.为什么glBindVertexArray解绑和绑定是一样的?glBindVertexArray是用来绑定和解绑顶点数组对象(VAO)的。绑定VAO的目的是告诉OpenGL在当前上下文中使用哪个VAO,它会保存和管理与该VAO相关的顶点缓冲区对象(VBO)和其他状态。绑定VAO(glBindVe
公务员行测之速算分数记忆检验-无答案版本
Lemon爱吃苹果
公务员 公务员 计算机
前言为了提高速算速度,有一些分数是必须要记忆的,这个博客是为了检验自己记忆效果的,答案在下一篇博客上面,自己查看哟!!!速算之分数记忆检验12=%\frac{1}{2}=\%21=%13=%\frac{1}{3}=\%31=%14=%\frac{1}{4}=\%41=%15=%\frac{1}{5}=\%51=%16=%\frac{1}{6}=\%61=%17=%\frac{1}{7}=\%71=
机器学习(Machine Learning)
七指琴魔御清绝
大数据学习
原文链接:http://blog.csdn.net/zhoubl668/article/details/42921187希望转载的朋友,你可以不用联系我.但是一定要保留原文链接,因为这个项目还在继续也在不定期更新.希望看到文章的朋友能够学到更多.《BriefHistoryofMachineLearning》介绍:这是一篇介绍机器学习历史的文章,介绍很全面,从感知机、神经网络、决策树、SVM、Ada
【Go语言圣经1.1】
Pyroyster
golang 开发语言 后端
目标学习Go的编译方式、包的组织方式以及工具链的统一调用方式概念与定义packageGo语言通过包来组织代码。包类似于其它语言的库librarries或模块modules,每个包通常对应一个目录,目录中的所有.go文件都属于同一个包。特殊的main包:当代码使用packagemain声明时,表示这是一个可独立执行的程序而非一个库。程序的执行入口就是main函数import通过import语句,编译
JWT在.NET8 Webapi中的使用
Evan.Pei
.net
JWT身份验证在现代Web应用中广泛使用,主要用于安全地传输用户身份信息.1.身份验证(用户登录后,服务器生成一个JWT并返回给客户端。客户端在后续请求中携带该JWT,服务器通过验证JWT来确认用户身份)2.授权(JWT中可以包含用户的角色或权限信息(如role:“admin”)。服务器根据JWT中的信息决定用户是否有权访问特定资源)3.信息交换(JWT可以包含一些非敏感的用户信息(如用户ID、用
多线程编程之理财
周凡杨
java 多线程 生产者 消费者 理财
现实生活中,我们一边工作,一边消费,正常情况下会把多余的钱存起来,比如存到余额宝,还可以多挣点钱,现在就有这个情况:我每月可以发工资20000万元 (暂定每月的1号),每月消费5000(租房+生活费)元(暂定每月的1号),其中租金是大头占90%,交房租的方式可以选择(一月一交,两月一交、三月一交),理财:1万元存余额宝一天可以赚1元钱,
[Zookeeper学习笔记之三]Zookeeper会话超时机制
bit1129
zookeeper
首先,会话超时是由Zookeeper服务端通知客户端会话已经超时,客户端不能自行决定会话已经超时,不过客户端可以通过调用Zookeeper.close()主动的发起会话结束请求,如下的代码输出内容
Created /zoo-739160015
CONNECTEDCONNECTED
.............CONNECTEDCONNECTED
CONNECTEDCLOSEDCLOSED
SecureCRT快捷键
daizj
secureCRT 快捷键
ctrl + a : 移动光标到行首ctrl + e :移动光标到行尾crtl + b: 光标前移1个字符crtl + f: 光标后移1个字符crtl + h : 删除光标之前的一个字符ctrl + d :删除光标之后的一个字符crtl + k :删除光标到行尾所有字符crtl + u : 删除光标至行首所有字符crtl + w: 删除光标至行首
Java 子类与父类这间的转换
周凡杨
java 父类与子类的转换
最近同事调的一个服务报错,查看后是日期之间转换出的问题。代码里是把 java.sql.Date 类型的对象 强制转换为 java.sql.Timestamp 类型的对象。报java.lang.ClassCastException。
代码:
可视化swing界面编辑
朱辉辉33
eclipse swing
今天发现了一个WindowBuilder插件,功能好强大,啊哈哈,从此告别手动编辑swing界面代码,直接像VB那样编辑界面,代码会自动生成。
首先在Eclipse中点击help,选择Install New Software,然后在Work with中输入WindowBui
web报表工具FineReport常用函数的用法总结(文本函数)
老A不折腾
finereport web报表工具 报表软件 java报表
文本函数
CHAR
CHAR(number):根据指定数字返回对应的字符。CHAR函数可将计算机其他类型的数字代码转换为字符。
Number:用于指定字符的数字,介于1Number:用于指定字符的数字,介于165535之间(包括1和65535)。
示例:
CHAR(88)等于“X”。
CHAR(45)等于“-”。
CODE
CODE(text):计算文本串中第一个字
mysql安装出错
林鹤霄
mysql安装
[root@localhost ~]# rpm -ivh MySQL-server-5.5.24-1.linux2.6.x86_64.rpm Preparing... #####################
linux下编译libuv
aigo
libuv
下载最新版本的libuv源码,解压后执行:
./autogen.sh
这时会提醒找不到automake命令,通过一下命令执行安装(redhat系用yum,Debian系用apt-get):
# yum -y install automake
# yum -y install libtool
如果提示错误:make: *** No targe
中国行政区数据及三级联动菜单
alxw4616
近期做项目需要三级联动菜单,上网查了半天竟然没有发现一个能直接用的!
呵呵,都要自己填数据....我了个去这东西麻烦就麻烦的数据上.
哎,自己没办法动手写吧.
现将这些数据共享出了,以方便大家.嗯,代码也可以直接使用
文件说明
lib\area.sql -- 县及县以上行政区划分代码(截止2013年8月31日)来源:国家统计局 发布时间:2014-01-17 15:0
哈夫曼加密文件
百合不是茶
哈夫曼压缩 哈夫曼加密 二叉树
在上一篇介绍过哈夫曼编码的基础知识,下面就直接介绍使用哈夫曼编码怎么来做文件加密或者压缩与解压的软件,对于新手来是有点难度的,主要还是要理清楚步骤;
加密步骤:
1,统计文件中字节出现的次数,作为权值
2,创建节点和哈夫曼树
3,得到每个子节点01串
4,使用哈夫曼编码表示每个字节
JDK1.5 Cyclicbarrier实例
bijian1013
java thread java多线程 Cyclicbarrier
CyclicBarrier类
一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点 (common barrier point)。在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时 CyclicBarrier 很有用。因为该 barrier 在释放等待线程后可以重用,所以称它为循环的 barrier。
CyclicBarrier支持一个可选的 Runnable 命令,
九项重要的职业规划
bijian1013
工作 学习
一. 学习的步伐不停止 古人说,活到老,学到老。终身学习应该是您的座右铭。 世界在不断变化,每个人都在寻找各自的事业途径。 您只有保证了足够的技能储
【Java范型四】范型方法
bit1129
java
范型参数不仅仅可以用于类型的声明上,例如
package com.tom.lang.generics;
import java.util.List;
public class Generics<T> {
private T value;
public Generics(T value) {
this.value =
【Hadoop十三】HDFS Java API基本操作
bit1129
hadoop
package com.examples.hadoop;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoo
ua实现split字符串分隔
ronin47
lua split
LUA并不象其它许多"大而全"的语言那样,包括很多功能,比如网络通讯、图形界面等。但是LUA可以很容易地被扩展:由宿主语言(通常是C或 C++)提供这些功能,LUA可以使用它们,就像是本来就内置的功能一样。LUA只包括一个精简的核心和最基本的库。这使得LUA体积小、启动速度快,从 而适合嵌入在别的程序里。因此在lua中并没有其他语言那样多的系统函数。习惯了其他语言的字符串分割函
java-从先序遍历和中序遍历重建二叉树
bylijinnan
java
public class BuildTreePreOrderInOrder {
/**
* Build Binary Tree from PreOrder and InOrder
* _______7______
/ \
__10__ ___2
/ \ /
4
openfire开发指南《连接和登陆》
开窍的石头
openfire 开发指南 smack
第一步
官网下载smack.jar包
下载地址:http://www.igniterealtime.org/downloads/index.jsp#smack
第二步
把smack里边的jar导入你新建的java项目中
开始编写smack连接openfire代码
p
[移动通讯]手机后盖应该按需要能够随时开启
comsci
移动
看到新的手机,很多由金属材质做的外壳,内存和闪存容量越来越大,CPU速度越来越快,对于这些改进,我们非常高兴,也非常欢迎
但是,对于手机的新设计,有几点我们也要注意
第一:手机的后盖应该能够被用户自行取下来,手机的电池的可更换性应该是必须保留的设计,
20款国外知名的php开源cms系统
cuiyadll
cms
内容管理系统,简称CMS,是一种简易的发布和管理新闻的程序。用户可以在后端管理系统中发布,编辑和删除文章,即使您不需要懂得HTML和其他脚本语言,这就是CMS的优点。
在这里我决定介绍20款目前国外市面上最流行的开源的PHP内容管理系统,以便没有PHP知识的读者也可以通过国外内容管理系统建立自己的网站。
1. Wordpress
WordPress的是一个功能强大且易于使用的内容管
Java生成全局唯一标识符
darrenzhu
java uuid unique identifier id
How to generate a globally unique identifier in Java
http://stackoverflow.com/questions/21536572/generate-unique-id-in-java-to-label-groups-of-related-entries-in-a-log
http://stackoverflow
php安装模块检测是否已安装过, 使用的SQL语句
dcj3sjt126com
sql
SHOW [FULL] TABLES [FROM db_name] [LIKE 'pattern']
SHOW TABLES列举了给定数据库中的非TEMPORARY表。您也可以使用mysqlshow db_name命令得到此清单。
本命令也列举数据库中的其它视图。支持FULL修改符,这样SHOW FULL TABLES就可以显示第二个输出列。对于一个表,第二列的值为BASE T
5天学会一种 web 开发框架
dcj3sjt126com
Web 框架 framework
web framework层出不穷,特别是ruby/python,各有10+个,php/java也是一大堆 根据我自己的经验写了一个to do list,按照这个清单,一条一条的学习,事半功倍,很快就能掌握 一共25条,即便很磨蹭,2小时也能搞定一条,25*2=50。只需要50小时就能掌握任意一种web框架
各类web框架大同小异:现代web开发框架的6大元素,把握主线,就不会迷路
建议把本文
Gson使用三(Map集合的处理,一对多处理)
eksliang
json gson Gson map Gson 集合处理
转载请出自出处:http://eksliang.iteye.com/blog/2175532 一、概述
Map保存的是键值对的形式,Json的格式也是键值对的,所以正常情况下,map跟json之间的转换应当是理所当然的事情。 二、Map参考实例
package com.ickes.json;
import java.lang.refl
cordova实现“再点击一次退出”效果
gundumw100
android
基本的写法如下:
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
//navigator.splashscreen.hide();
document.addEventListener("b
openldap configuration leaning note
iwindyforest
configuration
hostname // to display the computer name
hostname <changed name> // to change
go to: /etc/sysconfig/network, add/modify HOSTNAME=NEWNAME to change permenately
dont forget to change /etc/hosts
Nullability and Objective-C
啸笑天
Objective-C
https://developer.apple.com/swift/blog/?id=25
http://www.cocoachina.com/ios/20150601/11989.html
http://blog.csdn.net/zhangao0086/article/details/44409913
http://blog.sunnyxx
jsp中实现参数隐藏的两种方法
macroli
JavaScript jsp
在一个JSP页面有一个链接,//确定是一个链接?点击弹出一个页面,需要传给这个页面一些参数。//正常的方法是设置弹出页面的src="***.do?p1=aaa&p2=bbb&p3=ccc"//确定目标URL是Action来处理?但是这样会在页面上看到传过来的参数,可能会不安全。要求实现src="***.do",参数通过其他方法传!//////
Bootstrap A标签关闭modal并打开新的链接解决方案
qiaolevip
每天进步一点点 学习永无止境 bootstrap 纵观千象
Bootstrap里面的js modal控件使用起来很方便,关闭也很简单。只需添加标签 data-dismiss="modal" 即可。
可是偏偏有时候需要a标签既要关闭modal,有要打开新的链接,尝试多种方法未果。只好使用原始js来控制。
<a href="#/group-buy" class="btn bt
二维数组在Java和C中的区别
流淚的芥末
java c 二维数组 数组
Java代码:
public class test03 {
public static void main(String[] args) {
int[][] a = {{1},{2,3},{4,5,6}};
System.out.println(a[0][1]);
}
}
运行结果:
Exception in thread "mai
systemctl命令用法
wmlJava
linux systemctl
对比表,以 apache / httpd 为例 任务 旧指令 新指令 使某服务自动启动 chkconfig --level 3 httpd on systemctl enable httpd.service 使某服务不自动启动 chkconfig --level 3 httpd off systemctl disable httpd.service 检查服务状态 service h