BMC lighttpd kvm数据分析(websocket)

news2024/12/23 22:19:34

1.说明

  1. lighttpd源码: https://github.com/lighttpd/lighttpd1.4.git
  2. lighttpd wiki: https://redmine.lighttpd.net/projects/lighttpd/wiki/
  3. libfcgi: https://github.com/toshic/libfcgi/tree/master

注意:

  • 本章的代码仓库: https://gitee.com/wit_yuan/lighttpd_kvm

2.编译

2.1 lighttpd编译与web访问

lighttpd编译方法,可以参考文档:https://github.com/lighttpd/lighttpd1.4/blob/master/INSTALL,命令如下:

  $ cd lighttpd-1.4.xx
  $ ./autogen.sh
  $ ./configure -C
  $ make check
  $ /usr/bin/sudo make install

安装后文件路径:

$ ls /usr/local/sbin/lighttpd* -al
-rwxr-xr-x 1 root root 2023608 830 16:45 /usr/local/sbin/lighttpd
-rwxr-xr-x 1 root root   23080 830 16:45 /usr/local/sbin/lighttpd-angel

配置文件lighttpd.conf,使用:https://github.com/lighttpd/lighttpd1.4/blob/master/doc/config/lighttpd.conf。配置文件:modules.conf,使用https://github.com/lighttpd/lighttpd1.4/blob/master/doc/config/modules.conf。/etc/lighttpd/conf.d/access_log.conf使用https://github.com/lighttpd/lighttpd1.4/tree/master/doc/config/conf.d。
注释掉/etc/lighttpd/lighttpd.conf:

#server.username  = "lighttpd"
#server.groupname = "lighttpd"

修改/etc/lighttpd/lighttpd.conf内容:

server.document-root = "/home/wityuan/Desktop/lighttpd/lighttpd1.4-lighttpd-1.4.76/www
server.port = 8080
server.bind = "localhost"

在目录:/home/wityuan/Desktop/lighttpd/lighttpd1.4-lighttpd-1.4.76/www中添加test.html,内容:

<!DOCTYPE html>
<html>
        <head>    
                <title> first website </title></head><body>    
                <h1> welcome
                </h1>   
                <p>this is a param.
                </p>
        </body>
</html>

执行命令:

$ sudo mkdir /var/log/lighttpd
$ sudo touch /var/log/lighttpd/error.log

启动lighttpd:

# sudo /usr/local/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf

启动成功:

在这里插入图片描述

网络访问:

http://127.0.0.1:8080/test.html

在这里插入图片描述

  • 备注:

这一篇的文件配置可以参考文档: https://redmine.lighttpd.net/projects/lighttpd/wiki/InstallFromSource

2.2 libfcgi下载与编译测试

从网站https://github.com/toshic/libfcgi/tree/master下载代码。

编译,使用命令:

$ ./configure
$ make
$ sudo make install

如果编译不过去,修改文件examples/Makefile.in中的内容:

echo_cpp_LDADD = $(LIBDIR)/libfcgi++.la

改为:

echo_cpp_LDADD = $(LIBDIR)/libfcgi++.la $(LIBDIR)/libfcgi.la

最后,编译生成的目录信息如下:
在这里插入图片描述
在这里插入图片描述
编写程序文件cgitest1.c

#include <stdlib.h>
#include <string.h>
#include <syslog.h>
#include <alloca.h>
#include <fcgiapp.h>
#define LISTENSOCK_FILENO 0
#define LISTENSOCK_FLAGS 0
int main(int argc, char** argv) {
  openlog("testfastcgi", LOG_CONS|LOG_NDELAY, LOG_USER);
  int err = FCGX_Init(); /* call before Accept in multithreaded apps */
  if (err) { syslog (LOG_INFO, "FCGX_Init failed: %d", err); return 1; }
  FCGX_Request cgi;
  err = FCGX_InitRequest(&cgi, LISTENSOCK_FILENO, LISTENSOCK_FLAGS);
  if (err) { syslog(LOG_INFO, "FCGX_InitRequest failed: %d", err); return 2; }

  while (1) {
    err = FCGX_Accept_r(&cgi);
    if (err) { syslog(LOG_INFO, "FCGX_Accept_r stopped: %d", err); break; }
    char** envp;
    int size = 200;
    for (envp = cgi.envp; *envp; ++envp) size += strlen(*envp) + 11;
    char*  result = (char*) alloca(size);
    strcpy(result, "Status: 200 OK\r\nContent-Type: text/html\r\n\r\n");
    strcat(result, "<html><head><title>testcgi</title></head><body><ul>\r\n");

    for (envp = cgi.envp; *envp; ++envp) {
      strcat(result, "<li>"); 
      strcat(result, *envp); 
      strcat(result, "</li>\r\n");
    }

    strcat(result, "</ul></body></html>\r\n");
    FCGX_PutStr(result, strlen(result), cgi.out);
  }

  return 0;
}

编译命令:

# gcc cgitest1.c -o cgitest1 -lfcgi

修改文件/etc/lighttpd/modules.conf,增加内容:

...
server.modules              += ("mod_fastcgi")
fastcgi.debug = 1
fastcgi.server += ("/cgi" =>
((
"bin-path"    => "/home/wityuan/Desktop/lighttpd/cgicode/cgitest1",
"max-procs"   => 1,
"socket"    => "/tmp/fcgi_test.socket",
"check-local" => "disable",
"allow-x-send-file" => "enable"
)))
...

注意:

  • 1.如果运行报错:
$ /usr/local/bin/cgi-fcgi
/usr/local/bin/cgi-fcgi: error while loading shared libraries: libfcgi.so.0: cannot open shared object file: No such file or directory

可以参考:https://serverfault.com/questions/120233/how-to-configure-fastcgi-to-work-with-ligttpd-in-ubuntu

解决办法:

 export LD_LIBRARY_PATH=/usr/local/lib
  • 2.如果运行报错:
2024-08-30 23:59:14: (gw_backend.c.676) gw-backend failed to start: /xx/cgitest1
2024-08-30 23:59:14: (gw_backend.c.678) If you're trying to run your app as a FastCGI backend, make sure you're using the FastCGI-enabled version.  If this is PHP on Gentoo, add 'fastcgi' to the USE flags.  If this is PHP, try removing the bytecode caches for now and try again.

可以执行命令:

$ sudo ldconfig

重启lighttd服务器,可以看到有2个进程:

在这里插入图片描述

访问资源,截图如下:
在这里插入图片描述

2.3 websocket

2.3.1 资源

websocket的资源参考如下:

  • js创建websocket:https://websockets.spec.whatwg.org/#the-websocket-interface
  • websocket api:https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API
  • websocket-6455官方文档:https://datatracker.ietf.org/doc/html/rfc6455

实际上,如上内容均在lighttpd中可以看到:

  • https://redmine.lighttpd.net/projects/lighttpd/wiki/WebSockets
2.3.2 websocket js与后台程序通信

这里会用到网站所说的mod_wstunnel的功能:

mod_wstunnel is a WebSocket tunnel endpoint, terminating the websocket tunnel from a client. mod_wstunnel decodes websocket frames and then passes data (without websocket frames) to a backend, and in the opposite direction encodes responses from backend into websocket frames before sending responses to client.

1.配置stunnel

在文件/etc/lighttpd/modules.conf 中新增mod_wstunnel的配置:

..,
server.modules += ("mod_wstunnel")
$HTTP["url"] =~ "^/websocket" {
  wstunnel.server = (
    "" => ((
      "host" => "127.0.0.1",
      "port" => "8081"
    ))
  )
  wstunnel.frame-type = "text"
}
...

然后编写一个后台的server程序,内容如下:

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdlib.h>

// Should be same with the one in lihttpd.conf and index.html.
#define DEFAULT_PORT 8081
// Should be same with the one in lihttpd.conf.
#define DEFAULT_IP "127.0.0.1"

int main(int argc, char **argv)
{
    int server_socket = -1;
    int client_socket = -1;
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    char received_buffer[1024]; // Buffer for received.
    int received_len = -1;
    int sended_len = -1;
    int res = -1;
    socklen_t addr_len = sizeof(struct sockaddr);
    int index;

    // Create a socket.
    server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (server_socket < 0)
    {
        printf("Create socket failed: %s\n", strerror(errno));
        return -1;
    }

    // Bind the created socket on special IP and port.
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(DEFAULT_PORT);
    server_addr.sin_addr.s_addr = inet_addr(DEFAULT_IP);
    if (bind(server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0)
    {
        printf("Bind server failed: %s\n", strerror(errno));
        return -2;
    }
    printf("Socket[%d] has bond on port[%d] for IP address[%s]!\n",
           server_socket, DEFAULT_PORT, DEFAULT_IP);

    // Listen on the created socket.
    listen(server_socket, 10);

    while (1)
    {
        printf("Waiting and accept new client connect...\n");

        client_socket = accept(server_socket, (struct sockaddr *)&client_addr, &addr_len);
        if (client_socket < 0)
        {
            printf("Accept client socket failed: %s\n", strerror(errno));
            return -3;
        }

        printf("Accept new client[%d] socket[%s:%d]\n", client_socket,
               inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

        while (1)
        {
            memset(received_buffer, 0, sizeof(received_buffer));

            received_len = read(client_socket, received_buffer, sizeof(received_buffer));
            if (received_len < 0)
            {
                printf("Read data from client [%d] failed: %s\n", client_socket, strerror(errno));
                close(client_socket);
                break;
            }
            else if (0 == received_len)
            {
                printf("Client [%d] disconnected!\n", client_socket);
                close(client_socket);
                break;
            }
            else
            {
                printf("Read %d bytes from client[%d] and the data is : %s\n",
                       received_len, client_socket, received_buffer);
                // Send back the received buffer to client.
                sended_len = write(client_socket, received_buffer, received_len);
                if (sended_len < 0)
                {
                    printf("wWite data back to client[%d] failed: %s \n", client_socket,
                           strerror(errno));
                    close(client_socket);
                    break;
                }
            }
        }
        sleep(1);
    }

    if (client_socket)
    {
        close(client_socket);
    }
    close(server_socket);

    return 1;
}

编译,执行程序:

# gcc server1.c -o server1
# ./server1

webjs程序命名lighttpd1.4-lighttpd-1.4.76/www/websocket.js,内容如下:

  // 获取按钮和文本框元素
  const sendBtn = document.getElementById('sendBtn');
  const messageBox = document.getElementById('messageBox');
  
  // 创建 WebSocket 对象
  const socket = new WebSocket('ws://127.0.0.1:8080/websocket'); // 使用一个 WebSocket 服务器进行测试
  
  // 设置 WebSocket 连接打开时的回调函数
  socket.onopen = function() {
     console.log('WebSocket 连接已打开');
  };
  
  // 设置 WebSocket 接收到消息时的回调函数
  socket.onmessage = function(event) {
     console.log('WebSocket 接收到消息:', event.data);
     messageBox.value += event.data + '\n';
  };
  
  // 设置 WebSocket 发生错误时的回调函数
  socket.onerror = function() {
     console.log('WebSocket 发生错误');
  };
  
  // 设置 WebSocket 连接关闭时的回调函数
  socket.onclose = function() {
     console.log('WebSocket 连接已关闭');
  };
  
  // 点击按钮时发送消息
  sendBtn.onclick = function() {
     const message = 'Hello, WebSocket!';
     socket.send(message);
     messageBox.value += '发送消息: ' + message + '\n';
  };

之后,可以看到端口被占用,服务器在监听:
在这里插入图片描述
html资源命名为lighttpd1.4-lighttpd-1.4.76/www/websocket.html,内容:

<!DOCTYPE html>
<html>
<head>
   <meta charset="UTF-8">
   <title>WebSocket 示例</title>
</head>
<body>
   <button id="sendBtn">发送消息</button>
   <textarea id="messageBox" readonly></textarea>
   <script src="websocket.js"></script>
</body>
</html>

在浏览器中访问资源:
在这里插入图片描述
服务端收到数据:
在这里插入图片描述
注意:

  • 在网站: https://github.com/nori0428/mod_websocket上,有描述:DEAD.use lighttpd v1.4.46 or after w/ mod_proxy and mod_wstunnnel.,该项目已经停止维护,建议使用mod_wstunnnel了。服务器上AMI BMC的实现kvm,sol, cd-server还是在用mod_websocket

从https://github.com/nori0428/mod_websocket/tree/master摘录一下数据流:

client <--- ssl ---> lighttpd - mod_websocket <--- tcp ---> your websocket server

3.KVM,cd-server,sol 的实现数据分析(TBD).

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2093071.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3127.构造相同颜色的正方形

1.题目描述 给你一个二维 3 x 3 的矩阵 grid &#xff0c;每个格子都是一个字符&#xff0c;要么是 B &#xff0c;要么是 W 。字符 W 表示白色&#xff0c;字符 B 表示黑色。 你的任务是改变 至多一个 格子的颜色&#xff0c;使得矩阵中存在一个 2 x 2 颜色完全相同的正方形。…

无敌美少男和无敌美少女构建企业级私有仓库(harbor)

一&#xff1a;harbor简介 Harbor 是由 vmware 公司开源的企业级 Docker Registry 项目。 它提供了以下主要功能和特点&#xff1a; 基于角色的访问控制&#xff08;RBAC&#xff09;&#xff1a;可以为不同的用户和用户组分配不同的权限&#xff0c;增强了安全性和管理的灵…

Linux下的MySQL8.0报错:[Err]1055

Linux下的MySQL8.0报错&#xff1a;[Err]1055 报错信息解决办法 报错信息 在Linux环境下的MySQL里执行SQL语句报如下错误&#xff1a;[Err] 1055 - Expression #1 of ORDER BY clause is not in GROUP BY clause and contains nonaggregated column information_schema.PROFIL…

maven 父子工程创建详解

maven 父子工程创建详解 一、Maven工程继承关系 继承概念 maven继承是指的Maven的项目中&#xff0c;让一个项目从另外项目中继承配置信息的机制。继承可以让我们在多个项目中共享同一个配置信息&#xff0c;简化项目的管理和维护工作 继承作用&#xff1a;在父工程中统一管理…

Datawhale AI夏令营 第五期 CV方向 Task3笔记

Task3&#xff1a;上分思路——数据集增强与模型预测 Part1&#xff1a;数据增强 数据增强是机器学习和深度学习中的一种技术&#xff0c;通过在原始数据集上应用一系列变换来人工地增加数据样本的数量和多样性&#xff0c;从而提高模型的泛化能力&#xff0c;减少过拟合&…

简单的 nginx 学习

简单的 nginx 学习 1. nginx的安装 1.1 下载安装包 去官网下载对应的nginx包&#xff0c;推荐使用稳定版本&#xff0c;上传nginx到linux系统 1.2 安装依赖环境 安装gcc环境 yum install gcc-c安装PCRE库&#xff0c;用于解析正则表达式 yum install -y pcre pcre-develzlib压…

【立体匹配】双目相机外参自标定方法介绍

双目相机外参自标定方法 原理实践 双目相机外参自标定方法是一种无需固定标定板&#xff0c;在拍摄实际场景的两张图像时&#xff0c;通过计算两幅图像之间的匹配特征点对&#xff0c;结合相机的内参矩阵&#xff0c;来实时求解两个相机之间相对位置&#xff08;即外参&#xf…

ThermoParser 介绍

ThermoParser是一个工具包&#xff0c;用于简化专业材料科学代码产生的数据分析&#xff0c;以热电学为中心&#xff0c;但也适用于任何与电子和/或声子传输有关的内容。ThermoParser是一个Python库&#xff0c;它包含数据检索、操作和绘图的函数&#xff0c;只需几行代码就可以…

HashMap 链表转红黑树的阈值为何为 8

与一个重要的统计学原理——泊松分布密切相关&#xff1a;该原理阐明了在单位时间&#xff08;或面积、体积&#xff09;内&#xff0c;随机事件的平均发生次数遵循泊松分布 为什么这因子设定为0.5呢&#xff1f; 在忽略方差的情况下&#xff0c;哈希表容量占比的期望值约为 0.…

揭秘扩散模型:DDPM的数学基础与代码实现全攻略!

(DDPM) denoising diffusion probabilistic models 理论学习 本文价值 本文是 Diffusion 这一类模型的开山之作&#xff0c;首次证明 diffusion 模型能够生成高质量的图片&#xff0c;且奠定了所有后续模型的基本原理&#xff1a;加噪 --> 去噪。DDPM 模型的效果如下&#x…

springboot+vue+mybatis计算机毕业设计飞机订票系统+PPT+论文+讲解+售后

快速发展的社会中&#xff0c;人们的生活水平都在提高&#xff0c;生活节奏也在逐渐加快。为了节省时间和提高工作效率&#xff0c;越来越多的人选择利用互联网进行线上打理各种事务&#xff0c;然后线上管理系统也就相继涌现。与此同时&#xff0c;人们开始接受方便的生活方式…

IDEA向mysql写入中文字符时出现乱码问题

可参考该博客&#xff1a;https://www.cnblogs.com/bb1008/p/7704458.html 第一步是将IDEA软件中的编码方式全部改为utf8 File -> Settings -> Editor -> File Encodings 第二步是在数据库链接中加入 ?characterEncodingUTF-8

备战2024年全国大学生数学建模竞赛:蔬菜类商品的自动定价与补货决策

目录 一、引言 二、问题分析 三、解题思路 问题1&#xff1a;销售量分布规律及相互关系 问题2&#xff1a;品类级别的补货计划与定价策略 问题3&#xff1a;单品级别的补货计划与定价策略 问题4&#xff1a;补充数据的建议与分析 四、知识点解析 五、模型建立与求解 1…

没有永远免费的加速器,但是永远有免费的加速器【20240831更新】

没有永远免费的加速器&#xff0c;但是永远有免费的加速器【每日更新】 一、迅雷加速器&#xff08;免费时长最高38天&#xff09; 可免费时长&#xff1a;8天 如果是迅雷会员&#xff0c;则免费时长为38天 官网下载链接&#xff1a;迅雷加速器—迅雷官方出品&#xff0c;为快…

关于数字存储和byte[]数组的一些心得

前言 最近做项目&#xff0c;发现一些规律&#xff0c;比如数字的存储和字符串的存储&#xff0c;先说数字吧&#xff0c;最常见的整数&#xff0c;就涉及反码和补码&#xff0c;根据这些规则&#xff0c;甚至我们自己也能造一种数据存储结构&#xff0c;比如1个字节8bit&…

bbr 和 inflight 守恒的收敛原理

先看 bbr&#xff0c;以 2 条流 bw 收敛为例&#xff0c;微分方程组如下&#xff1a; { d x d t C ⋅ g ⋅ x g ⋅ x y − x d y d t C ⋅ g ⋅ y g ⋅ y x − y \begin{cases} \dfrac{dx}{dt}C\cdot\dfrac{g\cdot x}{g\cdot xy}-x\\\ \dfrac{dy}{dt}C\cdot\dfrac{g\cdot y…

秋风送爽,夏意未央|VELO Prevail Revo坐垫,一骑绿动起来吧~

夏末秋初&#xff0c;当第一片落叶缓缓飘落&#xff0c;是时候骑上你的自行车&#xff0c;迎接新的季节啦。带上维乐Prevail Revo坐垫&#xff0c;因为它独树一帜地采用EVA与回收咖啡渣精制而成的轻量发泡提升了减震性能&#xff0c;可以让你的每一次骑行都充满意义。    “…

基于DS18B20的温度检测

前言 DS18B20是DALLAS半导体公司生产的单总线数字温度传感器&#xff0c;其输出的是数字信号&#xff0c;具有体积小&#xff0c;功耗低&#xff0c;抗干扰能力强&#xff0c;精度高的特点。 温度范围-55摄氏度至125摄氏度&#xff0c;在-10摄氏度至85摄氏度可以达到不超过 0.5…

Redis进阶(五):集群

1.概念 集群&#xff0c;从广义来讲&#xff1a;只要是多个机器&#xff0c;构成了分布式系统&#xff0c;都可以称为一个集群 狭义的集群&#xff1a;redis提供的集群模式&#xff0c;这个集群模式之下&#xff0c;主要是要解决存储空间不足的问题&#xff08;拓展存储空间&…

分歧时间估计与被子植物的年代-文献精读43

Ad fontes: divergence-time estimation and the age of angiosperms 回归本源&#xff1a;分歧时间估计与被子植物的年代 摘要 准确的分歧时间对于解释和理解谱系演化的背景至关重要。在过去的几十年里&#xff0c;有关冠被子植物推测的分子年龄&#xff08;通常估计为晚侏罗…