强曰为道

与天地相似,故不违。知周乎万物,而道济天下,故不过。旁行而不流,乐天知命,故不忧.
文档目录

第 2 章:安装与环境搭建

2.1 环境准备

在安装 nanomsg / NNG 之前,确保系统已安装以下工具:

工具用途最低版本
C 编译器编译源码GCC 4.8+ / Clang 3.5+
CMake构建系统3.6+
Git克隆源码任意
Make构建工具GNU Make 3.81+

2.1.1 Ubuntu / Debian

sudo apt update
sudo apt install -y build-essential cmake git

2.1.2 CentOS / RHEL

sudo yum groupinstall -y "Development Tools"
sudo yum install -y cmake3 git
# cmake3 需要通过 alternatives 设置
sudo alternatives --install /usr/local/bin/cmake cmake /usr/bin/cmake3 20

2.1.3 macOS

xcode-select --install
brew install cmake

2.1.4 验证环境

gcc --version
cmake --version
git --version

2.2 安装 nanomsg

2.2.1 从源码编译

# 克隆仓库
git clone https://github.com/nanomsg/nanomsg.git
cd nanomsg

# 创建构建目录
mkdir build && cd build

# 配置
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local

# 编译(-j 指定并行数)
make -j$(nproc)

# 运行测试(可选)
ctest --output-on-failure

# 安装
sudo make install
sudo ldconfig

2.2.2 CMake 常用选项

选项默认值说明
CMAKE_INSTALL_PREFIX/usr/local安装路径
CMAKE_BUILD_TYPEDebug构建类型:Debug / Release
NN_ENABLE_DOCON是否生成文档
NN_TESTSON是否编译测试
NN_ENABLE_SPON是否编译可扩展性协议

Release 构建(推荐用于生产):

cmake .. -DCMAKE_BUILD_TYPE=Release \
         -DCMAKE_INSTALL_PREFIX=/usr/local \
         -DNN_TESTS=OFF
make -j$(nproc)
sudo make install

2.2.3 包管理器安装

# Ubuntu / Debian
sudo apt install -y libnanomsg-dev

# macOS
brew install nanomsg

# Fedora
sudo dnf install -y nanomsg-devel

注意:包管理器版本可能滞后于 GitHub 仓库,建议从源码编译以获取最新特性。

2.2.4 验证安装

# 检查头文件
ls /usr/local/include/nanomsg/

# 检查库文件
ls /usr/local/lib/libnanomsg*

# 编写测试程序
cat > /tmp/test_nn.c << 'EOF'
#include <stdio.h>
#include <nanomsg/nn.h>
#include <nanomsg/pair.h>

int main() {
    int sock = nn_socket(AF_SP, NN_PAIR);
    if (sock >= 0) {
        printf("nanomsg OK! Socket fd = %d\n", sock);
        nn_close(sock);
    } else {
        printf("nanomsg FAILED: %s\n", nn_strerror(nn_errno()));
    }
    return 0;
}
EOF

cc /tmp/test_nn.c -lnanomsg -o /tmp/test_nn
/tmp/test_nn
# 输出: nanomsg OK! Socket fd = 3

2.3 安装 NNG

2.3.1 从源码编译

# 克隆仓库
git clone https://github.com/nanomsg/nng.git
cd nng

# 创建构建目录
mkdir build && cd build

# 配置
cmake .. -DCMAKE_INSTALL_PREFIX=/usr/local \
         -DCMAKE_BUILD_TYPE=Release

# 编译
make -j$(nproc)

# 运行测试(可选)
ctest --output-on-failure

# 安装
sudo make install
sudo ldconfig

2.3.2 NNG CMake 常用选项

选项默认值说明
CMAKE_INSTALL_PREFIX/usr/local安装路径
CMAKE_BUILD_TYPEDebug构建类型
NNG_TESTSON是否编译测试
NNG_TOOLSON是否编译命令行工具
NNG_ENABLE_TLSOFF是否启用 TLS 支持
NNG_TRANSPORT_TCPON是否编译 TCP 传输
NNG_TRANSPORT_IPCON是否编译 IPC 传输
NNG_TRANSPORT_INPROCON是否编译 inproc 传输
NNG_TRANSPORT_WSON是否编译 WebSocket 传输
NNG_STATIC_LIBOFF是否编译静态库

启用 TLS 的构建:

cmake .. -DCMAKE_BUILD_TYPE=Release \
         -DNNG_ENABLE_TLS=ON \
         -DNNG_STATIC_LIB=ON \
         -DCMAKE_INSTALL_PREFIX=/usr/local
make -j$(nproc)
sudo make install

2.3.3 验证 NNG 安装

# 检查头文件
ls /usr/local/include/nng/nng.h

# 检查库文件
ls /usr/local/lib/libnng*

# 检查工具
nngcat --help

nngcat 是 NNG 自带的命令行调试工具,可用于快速测试消息传递:

# 终端 1:监听
nngcat --rep --listen tcp://*:5555

# 终端 2:发送
nngcat --req --dial tcp://localhost:5555 --data "Hello"

2.3.4 编写 NNG 测试程序

#include <stdio.h>
#include <nng/nng.h>
#include <nng/protocol/pair0/pair.h>

int main() {
    nng_socket sock;
    int rv = nng_pair0_open(&sock);
    if (rv == 0) {
        printf("NNG OK! Socket opened successfully.\n");
        nng_close(sock);
    } else {
        printf("NNG FAILED: %s\n", nng_strerror(rv));
    }
    return 0;
}
cc test_nng.c -lnng -o test_nng
./test_nng
# 输出: NNG OK! Socket opened successfully.

2.4 语言绑定

虽然 nanomsg / NNG 的核心是 C 库,但社区提供了丰富的语言绑定。

2.4.1 语言绑定一览

语言nanomsg 绑定NNG 绑定安装方式
Pythonpynanomsgpynngpip install pynng
Gogo-nanomsgmangosgo get
Rustnanomsg.rsnng-rsCargo
JavajnanomsgMaven
Node.jsnanomsgnpm install nanomsg
C#/.NETNNanomsgNNG.NETNuGet
Rubynanomsggem
Haskellnanomsg-haskellcabal
Erlangenmrebar
Lualua-nanomsgluarocks

2.4.2 Python 绑定示例

安装 pynng:

pip install pynng

REQ/REP 示例:

# server.py
from pynng import Rep0

with Rep0(listen='tcp://*:5555') as sock:
    while True:
        msg = sock.recv()
        print(f"Received: {msg.decode()}")
        sock.send(b'OK')
# client.py
from pynng import Req0

with Req0(dial='tcp://localhost:5555') as sock:
    sock.send(b'Hello, NNG!')
    reply = sock.recv()
    print(f"Reply: {reply.decode()}")

2.4.3 Go 绑定示例(mangos)

package main

import (
    "fmt"
    "log"
    "time"

    mangos "github.com/nanomsg/mangos"
    "github.com/nanomsg/mangos/protocol/req"
    "github.com/nanomsg/mangos/transport/tcp"
)

func main() {
    sock, err := req.NewSocket()
    if err != nil {
        log.Fatal(err)
    }
    defer sock.Close()

    sock.AddTransport(tcp.NewTransport())

    if err = sock.Dial("tcp://localhost:5555"); err != nil {
        log.Fatal(err)
    }

    if err = sock.Send([]byte("Hello, mangos!")); err != nil {
        log.Fatal(err)
    }

    reply, err := sock.Recv()
    if err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Reply: %s\n", string(reply))
}

2.4.4 Rust 绑定示例(nng-rs)

use nng::{Protocol, Socket};

fn main() -> Result<(), nng::Error> {
    let sock = Socket::new(Protocol::Pair0)?;
    sock.dial("tcp://localhost:5555")?;
    sock.send(b"Hello, NNG!")?;
    let msg = sock.recv()?;
    println!("Reply: {}", String::from_utf8_lossy(&msg));
    Ok(())
}

Cargo.toml 依赖:

[dependencies]
nng = "1.0"

2.5 静态库构建

在某些场景下(嵌入式部署、简化分发),需要将 nanomsg / NNG 编译为静态库。

2.5.1 nanomsg 静态库

cd nanomsg
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
         -DCMAKE_POSITION_INDEPENDENT_CODE=ON
make -j$(nproc)

# 静态库位置
ls libnanomsg.a

链接静态库:

cc myapp.c -L. -lnanomsg -lpthread -lrt -o myapp

2.5.2 NNG 静态库

cd nng
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
         -DNNG_STATIC_LIB=ON
make -j$(nproc)

# 静态库位置
ls libnng.a

2.5.3 在 CMake 项目中使用

cmake_minimum_required(VERSION 3.10)
project(myapp C)

find_package(nng REQUIRED)

add_executable(myapp main.c)
target_link_libraries(myapp nng::nng)

2.5.4 使用 pkg-config

# nanomsg
cc myapp.c $(pkg-config --cflags --libs nanomsg) -o myapp

# NNG
cc myapp.c $(pkg-config --cflags --libs libnng) -o myapp

2.6 自定义安装路径

如果需要安装到非标准路径(如用户目录),可在 CMake 中指定:

cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/local/nng
make -j$(nproc)
make install

# 使用时指定路径
cc myapp.c -I$HOME/local/nng/include \
           -L$HOME/local/nng/lib \
           -lnng \
           -Wl,-rpath,$HOME/local/nng/lib \
           -o myapp

2.6.1 设置环境变量

# 添加到 ~/.bashrc 或 ~/.zshrc
export NNG_HOME=$HOME/local/nng
export PATH=$NNG_HOME/bin:$PATH
export CPATH=$NNG_HOME/include:$CPATH
export LIBRARY_PATH=$NNG_HOME/lib:$LIBRARY_PATH
export LD_LIBRARY_PATH=$NNG_HOME/lib:$LD_LIBRARY_PATH
export PKG_CONFIG_PATH=$NNG_HOME/lib/pkgconfig:$PKG_CONFIG_PATH

2.7 CMake 集成模板

推荐的项目结构:

myproject/
├── CMakeLists.txt
├── src/
│   └── main.c
└── third_party/
    └── nng/          # NNG 源码(可选,作为子模块)

方式 1:系统安装的库

cmake_minimum_required(VERSION 3.10)
project(myproject C)

set(CMAKE_C_STANDARD 11)

find_package(nng REQUIRED)

add_executable(myproject src/main.c)
target_link_libraries(myproject nng::nng)

方式 2:FetchContent 自动下载

cmake_minimum_required(VERSION 3.14)
project(myproject C)

include(FetchContent)

FetchContent_Declare(
    nng
    GIT_REPOSITORY https://github.com/nanomsg/nng.git
    GIT_TAG        v1.8.0
)
FetchContent_MakeAvailable(nng)

add_executable(myproject src/main.c)
target_link_libraries(myproject nng)

方式 3:Git Submodule

git submodule add https://github.com/nanomsg/nng.git third_party/nng
cmake_minimum_required(VERSION 3.10)
project(myproject C)

add_subdirectory(third_party/nng)

add_executable(myproject src/main.c)
target_link_libraries(myproject nng)

2.8 常见问题排查

2.8.1 编译错误

错误原因解决方案
CMake not found未安装 CMakeapt install cmake
nng.h: No such file头文件未安装或路径错误检查 CMAKE_INSTALL_PREFIX
undefined reference to nng_*链接器找不到库添加 -lnng 或检查 LIBRARY_PATH
libnng.so: cannot open shared object运行时找不到动态库sudo ldconfig 或设置 LD_LIBRARY_PATH

2.8.2 TLS 编译问题

# 如果启用 TLS 报错找不到 mbedTLS
sudo apt install -y libmbedtls-dev

# 或使用 OpenSSL
cmake .. -DNNG_ENABLE_TLS=ON -DNNG_TLS_ENGINE=openssl

2.8.3 运行时权限问题

# IPC 使用 Unix Socket 时,可能需要目录权限
mkdir -p /tmp/nng_sockets
chmod 777 /tmp/nng_sockets

2.9 注意事项

版本选择:nanomsg 最新稳定版为 1.1.5(2018 年),NNG 最新版为 1.8+(2024 年活跃开发中)。新项目务必使用 NNG。

ABI 兼容性:NNG 的 ABI 在大版本间不保证向后兼容,升级时需重新编译应用。

交叉编译:嵌入式场景需要交叉编译时,需在 CMake 中指定工具链文件:

cmake .. -DCMAKE_TOOLCHAIN_FILE=/path/to/toolchain.cmake

2.10 扩展阅读


上一章第 1 章:nanomsg / NNG 概述 | 下一章第 3 章:可扩展性协议详解