在C中求解Web应用程序问题 - 最绿色的编程语言
#网络开发人员 #mysql #mariadb #nginx

C语言和网络

即使世界上大量的网络基础架构都写在C中,但大多数人都不想写C编写Web应用程序。鉴于缺乏易于使用的网络和数据库结构,这是可以理解的,与网络服务器无直接连接,安全问题,仅举几例。

但是,

c是世界上最绿色的编程语言,如果我们想帮助环境,这很重要。当然,如果您想要最好的表现,C是使用的语言。

本文将展示如何利用C的力量并解决上述问题。

什么是Vely?

Vely是C开发人员的通用框架。使用Vely创建的应用程序是本机,没有解释器或字节代码方案。有关更多信息,请参见Vely.dev。

您将编写和运行的应用程序

您将编写维护员工列表的人力资源(HR)Web应用程序。它很简单,并不完全是钟声和哨子,但它表现得足以开始。而且,您将不希望有一个教程来学习学习的各种东西,您可以轻松地自行添加。这里的目的是学习基础知识。

因此,这有三个部分。首先是添加员工。第二个显示员工名单。第三个是能够从列表中删除员工。

开始之前:

  1. 安装Vely。您可以使用APT,DNF,Zypper或Pacman等标准包装器。转到https://vely.dev/pkg/安装Vely。您可以随时使用同一包装器删除它,
  2. 为您的项目创建目录 - 您可以将其命名为任何所需的内容。在此处完成的所有工作都应该在该目录中完成
  3. 确保您已安装了Mariadb和Nginx,就像在此处使用。

应用程序的屏幕截图

这是应用程序的快照。这是最终结果。

添加员工的Web表单:

Add employee

添加员工的结果:

Added employee

列出员工:

List employees

您也可以删除员工,之后它将不再存在。

Vely-它如何工作

在本文中,您将为应用程序创建源代码文件。这些文件具有.vely扩展名。

这些文件中的源代码是c,其中包含Vely语句。每个语句将生成某些C代码,因此最终结果始终是C。这就是Vely的工作方式。

使Vely成为框架的部分是请求处理 - 简单的调度程序为标准HTTP请求处理提供了基础。还有一个自动内存垃圾收集器,它对诸如Web Application Daemons之类的长期运行过程很有用。

最重要的是,Vely代码将自身变成纯C,然后将其编译为本机应用程序。

使用SQL简介

首先,我将讨论使用数据库,因为它是数据库驱动的Web应用程序的基础。

Vely当前支持Mariadb/MySQL,PostgreSQL和SQLITE数据库。它们中的任何一个都是相同的。例如,查询表员工并显示找到的名称列表,此处是Vely代码:

run-query @db = \
    "select firstName, lastName from employee where employeeID='%s'" \
    output firstName, lastName \
    : empid

    @Employee is <<query-result  firstName>> <<query-result  lastName>>
end-query

在编码Vely时,要牢记一些事情:

线延续

请注意,Backslash(\)的用法与C中一样表示线的延续。因此,前三行代码是一个单个语句。

输出数据

要向Web客户端(例如浏览器)或标准输出显示数据,请使用输出语句,即在行开头的@

数据库配置

使用@子句指定数据库,在这种情况下是@db。这是保存本机数据库连接信息的文件。每个数据库都有自己的;在这种情况下,您正在使用MariadB(或MySQL),因此File DB可能具有以下内容:

[client]  
user=user_name 
password=password     
database=database_name     
socket=/run/mysqld/mysqld.sock

您可以阅读更多有关MariadB/MySQL编写连接字符串信息的详细信息。 Vely使用本机数据库连接进行性能,并且连接详细信息也是本机的。这涵盖了您需要使用Vely中查询数据库的大部分内容。

数据库查询

要运行查询,请使用run-query语句。通常,它陈述使用的数据库(带有@子句),查询本身和输出列列表(带有output子句)。您在:子句之后为SQL语句提供输入参数。

查询结果

要显示查询结果集中的列数据,请使用query-result语句。当在输出中使用,就像这里一样,您可以将其放置在<<>>中 - 这是Inline Code。

查询循环

如果要循环循环浏览查询的结果集,请用end-query语句标记此循环的结束,如上所述。

步骤1:入门 - 数据库

首先,您将创建此处使用的数据库和员工表。此示例中的SQL很简单,因此您可以使用所需的任何数据库供应商。不过,在这里,使用了Mariadb。创建员工表的SQL如下。将此保存到设置。SQL文件:

create table if not exists employee (
    firstName varchar(50),
    lastName varchar(50),
    employeeID integer primary key auto_increment);

作为root用户(数据库管理员)登录到mySQL实用程序,并执行此功能以创建数据库,用户和员工表:

create database if not exists emp;
create user if not exists appuser identified by 'my_password';
grant create,alter,drop,select,insert,delete,update 
    on emp.* to appuser;
use emp;
source setup.sql;
exit

最后,Vely需要知道您的数据库在哪里。创建数据库配置文件db(这是run-query语句中使用的名称)。将其复制到文件db

[client]
user=appuser
password=my_password
database=emp
protocol=TCP
host=127.0.0.1
port=3306

注意appuseremp数据库(以及密码)与您在MySQL实用程序中执行的创建SQL中相同。

步骤2:源代码

这是源代码。按照指示复制并将代码粘贴到文件。

列出员工(查询表)

这将显示员工表中的员工列表。只是为了说明任何C代码的用法(由于这里的大多数代码是Vely语句),因此我添加了C代码以找出流程ID(PID)并显示它。将此保存到emp.vely文件:

#include "vely.h"

void emp()
{
    out-header default

    @<!DOCTYPE html>
    @<html>
    @<head><title>Vely example</title></head>
    @<body>

    pid_t pid = getpid(); // get current process ID

    @Employee report from process <<pf-out "%d", pid>>
    @<hr/>

    @<table border="1">

    run-query @db = \
        "select firstName, lastName, employeeID from employee" \
        output firstName, lastName, employeeID

        @<tr>
            @<td> <<query-result lastName>> </td>
            @<td> <<query-result firstName>> </td>
            @<td> \
                <a href="?req=del_emp\
                    &employee_id=<<query-result employeeID>>">\
                    Delete\
                </a> </td>
        @</tr>
    end-query
    @</table>
    @</body>
    @</html>
 }

如您所见,输出语句@经常使用。它输出在同一行上遵循的任何文本。由于相同的Vely程序​​可以用作Web应用程序和命令行程序,因此输出的目的地取决于您的使用方式。如果是Web应用程序,则输出将输入Web客户端,即浏览器。如果是命令行程序,则输出将输入标准输出,即stdout

在输出数据时,内联代码通常用作输出的一部分。内联代码是在<<>>之间编写的,通常调用输出某些内容的Vely语句。在此示例中,query-result输出查询结果集的列值。

注意,您可以通过单击删除链接来删除员工记录。该链接回电您的应用程序,并指定基于嵌入在删除链接中的employeeID删除的员工记录。

所有Vely请求都必须具有req输入参数,以指定.vely文件将处理该请求的内容。因此,当用户单击链接时,del_emp.vely中的代码将运行。即将到来。

添加员工(插入表)

要将数据插入员工表中,将作为输入参数提供员工的名字和姓氏。通过使用input-param语句在Vely框架中获得这些简单。然后,Insert SQL将使用run-query插入数据,该数据使用no-loop子句说没有结果集循环(即,这不是选择查询),而affected-rows可以获取实际插入的行数。最后,您将检查是否按预期插入一行,并通知用户。将此代码保存到add_emp.vely文件:

#include "vely.h"

void add_emp() {
    out-header default

    input-param first_name
    input-param last_name

    run-query @db = \
        "insert into employee (firstName, lastName) \
            values ('%s', '%s')" \
        : first_name, last_name \
        no-loop \
        affected-rows define aff_rows

    if (aff_rows != 1) {
        @Could not add employee!
        exit-request
    }

    @Employee added
}

添加员工的Web表单

为了添加员工,您将需要一个Web表单来输入它们,然后将其作为输入参数发送到add_emp.vely进行处理。这是一个简单的形式,可以做到这一点 - 注意将?用作<form>元素中的动作属性。它的意思是:使用引导此处的相同的URL路径,然后从Form的输入字段中添加URL查询字符串。注意隐藏的字段req,这是一个强制性字段,以便路由HTTP请求 - 毫不奇怪,它包含add_emp。将此保存到form_add_emp.vely文件:

#include "vely.h"

void form_add_emp() {
    out-header default

    @<h2>Enter employee</h2>

    @<form action="?" method="POST">
    @    <input type="hidden" name="req" value="add_emp">

    @    <label for="first_name">First name:</label><br>
    @    <input type="text" name="first_name" value=""><br>

    @    <label for="last_name">Last name:</label><br>
    @    <input type="text" name="last_name" value=""><br><br>

    @    <input type="submit" value="Submit">
    @ </form>
}

删除员工(从表中删除)

删除员工记录将获取员工ID,并发布删除SQL语句。请注意使用:子句的使用,该子句可以指定SQL输入参数,在这种情况下为employee_id被删除。将此保存到del_emp.vely文件:

#include "vely.h"

void del_emp() {
    out-header default

    input-param employee_id

    run-query @db = \
        "delete from employee where employeeID='%s'" : employee_id \
        no-loop \
        affected-rows define aff_rows

    if (aff_rows == 1) {
        @Employee record deleted.
    } else {
        @Could not delete an employee record.
    }
}

步骤3:创建应用程序

要创建Vely应用程序,请执行此操作:

sudo vf -i -u $(whoami) emp

-i说创建一个Vely应用程序,-u说它的所有者将是当前用户,而emp是应用程序名称。

这将创建Directory /var/lib/vv/emp,这是您项目的应用程序目录(请参阅how Vely works)。您已经对其进行了初始化并设置权限,以允许当前用户使用此目录,而其他用户无法访问它。

步骤4:进行申请

您现在在项目中有以下文件:emp.velyform_add_emp.velyadd_emp.velydel_emp.velydb。 Vely的vv utility将从它们中删除应用程序 - 它将自动找到这些文件并为您生成适当的makefile并在必要的库中链接。

您可以使用vv:
进行应用程序

vv -q --db=mariadb:db

-q说您正在制作申请。 --db说您正在使用MariaDB数据库,并且数据库配置文件位于文件db中。

注意,您可以在应用程序中使用多个数据库,也可以从不同的供应商中使用。

步骤5:运行应用程序

您将作为FastCGI应用程序服务器运行该应用程序。您的应用程序服务器在Web服务器后面运行(在这种情况下为NGINX),该服务器充当逆向电视。许多持续和并发服务的服务器流程将服务于传入的请求。这些过程不退出,它们并联起作用。另外,最终用户无法直接访问它们。

启动您的应用程序:

vf -w 5 emp

这将启动5个并发过程。阅读有关vf - Vely's FastCGI process manager的信息,以获取有关如何微调性能的更多信息,包括设置一个动态过程加载程序,该加载器根据实际运行时加载来改变运行的过程数量。

步骤6:Fastcgi的设置nginx

最后一步是在这种情况下设置Web服务器,Nginx。编辑nginx配置文件 - 为Ubuntu和类似Linux发行版:

sudo vi /etc/nginx/sites-enabled/default

和Fedora,例如Redhat:

sudo vi /etc/nginx/nginx.conf

server {}部分中添加以下内容:

location /emp { include /etc/nginx/fastcgi_params; fastcgi_pass unix:///var/lib/vv/emp/sock/sock; }

重新启动nginx以生效:

sudo systemctl restart nginx

您在这里所做的就是将URL路径/emp与NGINX和您的应用程序服务器之间的Super-Fast Unix套接字连接连接。这样的URL喜欢:

http://<your web server>/emp?req=add_emp&first_name=Joe&last_name=Darling

将在文件add_emp.vely中调用功能add_emp(),名为输入参数。

就是这样

您现在有一个功能应用程序可以使用。以下描述了使用它的各种方法。

使用Web浏览器的应用程序

以下URL是您应用程序的接口。使用两者都运行它。首先是添加员工:

http://<your web server>/emp?req=form_add_emp

这是列出员工

http://<your web server>/emp?req=emp

当然,用“ 127.0.0.1”回环地址(如果您在本地进行测试)或Web服务器的完全合格的名称或IP地址。

注意这些事实:

  1. URL路径是您的应用程序的名称-/emp在这种情况下,因为您如何使用Nginx进行设置,
  2. req参数始终是处理它的请求源文件的基本名称。例如,URL中的req=form_add_emp表示form_add_emp.vely中的代码将处理该请求,
  3. 您可以自由选择的任何其他参数。

请注意,如果您没有Web服务器,并且仍然要使用应用程序服务器,则可以在Vely安装中包含的FASTCGI客户端直接在命令行上与它联系(因此绕过Web服务器) 。在这种情况下,您将要求您的应用程序服务器列出员工记录:

export REQUEST_METHOD=GET
export QUERY_STRING='req=emp'
cgi-fcgi -connect /var/lib/vv/emp/sock/sock /

命令行的用法

每个Vely应用程序都可以作为Web应用程序或命令行程序运行。他们都使用HTTP作为协议,使得以多种不同方式易于开发,测试,维护和使用该应用程序。

请注意,如果您计划仅从命令行运行应用程序,则不需要应用程序服务器,因此在这种情况下,您不需要Web服务器设置,也不需要启动应用程序服务器使用VF流程管理器。这要简单得多。

要从命令行运行您的应用程序,请在命令行上提供输入参数并运行程序。例如,要添加员工,请提供REQUEST_METHOD环境变量(例如GET)和QUERY_STRING(设置为URL添加员工),并调用程序:

export REQUEST_METHOD=GET
export QUERY_STRING='req=add_emp&first_name=Joe&last_name=Darling'
/var/lib/vv/bld/emp/emp

结果是:

Content-type: text/html;charset=utf-8
Cache-Control: max-age=0, no-cache
Pragma: no-cache
Status: 200 OK

Employee added

如果您打算将结果保存在文件中(例如用于缓存应用程序输出),则可以通过这样做来省略输出中的HTTP标头:

export VV_SILENT_HEADER=yes

结论

在本教程中,您已经学习了如何使用Vely创建完整功能的数据库驱动的Web应用程序,该应用程序将MariadB/MySQL用作数据库和NGINX作为反向Proxy Web服务器。

例如,您可以使用PostgreSQL和Apache,并且非常相似。

您还学会了如何以不同的方式运行应用程序:作为应用程序服务器或命令行。输出和行为完全相同,这对于部署和自动化应用程序测试都是有用的。

封面图像版权(C)2022 Sergio Mijatovic