IPFS星际文件存储私有多结点部署_ipfs 多节点部署-程序员宅基地

技术标签: blokcchain区块链综合  IPFS  F  

一、IPFS概述

IPFS(Inter Planetary File System)是一个点对点的分布式超媒体分发协议,它整合了过去几年最好的分布式系统思路,为所有人提供全球统一的可寻址空间,包括Git、自证明文件系统SFS、BitTorrent和DHT,同时也被认为是最有可能取代HTTP的新一代互联网协议。

IPFS用基于内容的寻址替代传统的基于域名的寻址,用户不需要关心服务器的位置,不用考虑文件存储的名字和路径。我们将一个文件放到IPFS节点中,将会得到基于其内容计算出的唯一加密哈希值。哈希值直接反映文件的内容,哪怕只修改1比特,哈希值也会完全不同。当IPFS被请求一个文件哈希时,它会使用一个分布式哈希表找到文件所在的节点,取回文件并验证文件数据。

IPFS是通用目的的基础架构,基本没有存储上的限制。大文件会被切分成小的分块,下载的时候可以从多个服务器同时获取。IPFS的网络是不固定的、细粒度的、分布式的网络,可以很好的适应内容分发网络的要求。这样的设计可以很好的共享各类数据,包括图像、视频流、分布式数据库、整个操作系统、模块链、 数据备份,还有静态网站。

IPFS提供了一个友好的WEB访问接口,用户可通过http://ipfs.io/hash 获取IPFS公共网络中的内容,也许在不久的将来,IPFS协议将会彻底替代传统的HTTP协议。

也可以根据业务需要,搭建自己私有结点的IPFS系统。

 在区块链工程项目中,IPFS一般用于区块链网络中大文件的存放,是区块链网络有力的补充。

二、准备环境

1、系统环境:ubuntu-18.04.1-live-server-amd64.ios

2、语言环境:go1.11.2.linux-amd64.tar.gz (下载网址:https://golang.org/dl/ ,下载不了是因为被“墙”了)

3、IPFS软件:go-ipfs_v0.4.18_linux-amd64.tar.gz (下载网址:https://github.com/ipfs/go-ipfs/releases/tag/v0.4.18

4、两个服务器IP为:192.168.1.100,192.168.1.101

 

三、安装Golang语言环境

sudo tar -C /usr/local -xzf go1.11.2.linux-amd64.tar.gz

export PATH=$PATH:/usr/local/go/bin

四、安装IPFS

cd ~

tar xvfz go-ipfs_v0.4.18_linux-amd64.tar.gz    #解压缩

cd go-ipfs/

sudo ./install.sh                         #安装IPFS

五、初始化IPFS

ipfs init    #初始化IPFS

该操作执行后,默认会在~目录下生成一个隐藏目录.ipfs,作为ipfs的local存储

cd ~/.ipfs

ll    #查看.ipfs中安装的内容

drwxrwxr-x  5 he he 4096 Nov 22 15:51 ./ 
drwxr-xr-x  6 he he 4096 Nov 24 13:25 ../ 
-rw-rw-r--  1 he he   27 Nov 22 15:51 api 
drwxr-xr-x 32 he he 4096 Nov 22 15:54 blocks/ 
-rw-rw----  1 he he 5278 Nov 22 15:46 config 
drwxr-xr-x  2 he he 4096 Nov 22 15:51 datastore/ 
-rw-------  1 he he  190 Nov 22 15:09 datastore_spec 
drwx------  2 he he 4096 Nov 22 15:09 keystore/ 
-rw-rw-r--  1 he he    0 Nov 22 15:51 repo.lock 
-rw-r--r--  1 he he    2 Nov 22 15:09 version

(以上三至五步分别在两台服务器上执行)

六、生成共享Key

我们要组建的是私有网络,所有节点需要使用相同的私有key来加入网络中,我们要使用go来下载go-ipfs-swarm-key-gen工具来生成共享key


go get github.com/Kubuxu/go-ipfs-swarm-key-gen  #编译工具 
cd $GOPATH 
cd go/src/github.com/Kubuxu/go-ipfs-swarm-key-gen/ipfs-swarm-key-gen/ 
go build 
./ipfs-swarm-key-gen > ~/.ipfs/swarm.key      # 生成key 
cd ~/.ipfs/

cat swarm.key    #查看密钥内容 
/key/swarm/psk/1.0.0/ 
/base16/ 
afc9b81ccb00cf58ad0d0bb2fd7b26193e97451492c223770582b0aaed46b3eb

scp ~/.ipfs/swarm.key 192.168.1.100:/home/he/.ipfs/   #将当前服务器下生成的key拷贝到192.168.1.100的相同目录下

六、移除默认的bootstrap节点

ipfs bootstrap rm –all

removed /dnsaddr/bootstrap.libp2p.io/ipfs/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN 
removed /dnsaddr/bootstrap.libp2p.io/ipfs/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa 
removed /dnsaddr/bootstrap.libp2p.io/ipfs/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb 
removed /dnsaddr/bootstrap.libp2p.io/ipfs/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt 
removed /ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ 
removed /ip4/104.236.179.241/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM 
removed /ip4/104.236.76.40/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64 
removed /ip4/128.199.219.111/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu 
removed /ip4/178.62.158.247/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd 
removed /ip6/2400:6180:0:d0::151:6001/tcp/4001/ipfs/QmSoLSafTMBsPKadTEgaXctDQVcqN88CNLHXMkTNwMKPnu 
removed /ip6/2604:a880:1:20::203:d001/tcp/4001/ipfs/QmSoLPppuBtQSGwKDZT2M73ULpjvfd3aZ6ha4oFGL1KrGM 
removed /ip6/2604:a880:800:10::4a:5001/tcp/4001/ipfs/QmSoLV4Bbm51jM9C4gDYZQ9Cy3U6aXMJDAbzgu2fzaDs64 
removed /ip6/2a03:b0c0:0:1010::23:1001/tcp/4001/ipfs/QmSoLer265NRgSp2LA3dPaeykiS1J6DifTC88f5uVQKNAd

 

七、加入结点

  • 在192.168.1.100服务器上查询节点ID:

ipfs id


        "ID": "QmTep4vpFo8G9vp6m6PLyyz4MX3DufMB39WiFQQbPHUJPD", 
        "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCY41neG2vMSiU1DkW6TneojCChDGO/V9Uy/9jn0eBkvl0SF5Vqj1c3zQwzat3Nhc5vrxZn6ffSpcR5bPUbt8zEl53AJ7y7lcP9a1w+iUe4Ht8X2NWMRVTHprSml82id8pDpf3hPM554BbjM63ulmX12N/mOG3BSN9WN+0AQHH+qbwSjdWrwYXplXAbyjMztW9T+7fXruCG0uT8Js8Uuj7/u9mbnbgmFvx1dsnLMaa2LA5fqkyAeIMvC3SIvHgmbnX69qzjZn3CN6r1FFfY/LxMOr0GKkUmh3WXmxCWUCf//+rtHoUwypbIoL0SNOSbPLxS+dZMpC0W2EJlbfrVlP/NAgMBAAE=", 
        "Addresses": null, 
        "AgentVersion": "go-ipfs/0.4.18/", 
        "ProtocolVersion": "ipfs/0.1.0" 
}

  • 在192.168.1.101服务器上查询节点ID:

ipfs id


        "ID": "QmYNYDp5PEi64dgTYRdci3XhtmQEnZVBQTATinWw6fq3Ac", 
        "PublicKey": "CAASpgIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpF9xJrTde996NuhNmED5Xg90wRqvtMQJtovRcq5o79DldeQeuKe9ket7/+TIs5Cn+QQekwJCClmBWh7e+xNL8RP5Mer0fABw4yAESR8E0PhJhcbI0Wlgh2X18NBFUmriIZqzcKedX5MzPa7yFhNoDtGotAmXb9smoVIRZVOg9CqR0xG0RqeFwBZGXCtaeRxK18oFHNwZ3t6G5xycvyeXpYxIoDfqUO7mb7c1g1MTn3gOyUbi4kAZvWAAfdmnPiCEI7nHyhMY0ZOJqaqPh8AOxuVLtcHgPYfRgHU+QMkcEHVMzz2Pu41LLS2NWs8i8CjM5N+EBuorndWN2LfEd0xeNAgMBAAE=", 
        "Addresses": null, 
        "AgentVersion": "go-ipfs/0.4.18/", 
        "ProtocolVersion": "ipfs/0.1.0" 
}

  • 在192.168.1.100服务器上加入节点ID192.168.1.101:

ipfs bootstrap add /ip4/192.168.1.101/tcp/4001/ipfs/QmYNYDp5PEi64dgTYRdci3XhtmQEnZVBQTATinWw6fq3Ac

  • 在192.168.1.101服务器上加入节点192.168.1.100:

ipfs bootstrap add /ip4/192.168.1.100/tcp/4001/ipfs/QmTep4vpFo8G9vp6m6PLyyz4MX3DufMB39WiFQQbPHUJPD

八、配置节点文件(实际上移除结点、增加结点等操作实现都最终在修改config文件)

cd ~/.ipfs

vim config


  "API": { 
    "HTTPHeaders": {} 
  }, 
  "Addresses": { 
    "API": "/ip4/127.0.0.1/tcp/5001",     #127.0.0.1改为所在服务器IP 
    "Announce": [], 
    "Gateway": "/ip4/127.0.0.1/tcp/8080", 
    "NoAnnounce": [], 
    "Swarm": [ 
      "/ip4/0.0.0.0/tcp/4001", 
      "/ip6/::/tcp/4001" 
    ] 
  }, 
  "Bootstrap": [ 
    "/ip4/192.168.1.101/tcp/4001/ipfs/QmYNYDp5PEi64dgTYRdci3XhtmQEnZVBQTATinWw6fq3Ac" 
  ],       #使用ipfs bootstrap add 命令加入的对方节点 
  "Datastore": { 
    "BloomFilterSize": 0, 
    "GCPeriod": "1h", 
    "HashOnRead": false, 
    "Spec": { 
      "mounts": [ 
        { 
          "child": { 
            "path": "blocks", 
            "shardFunc": "/repo/flatfs/shard/v1/next-to-last/2", 
            "sync": true, 
            "type": "flatfs" 
          }, 
          "mountpoint": "/blocks", 
          "prefix": "flatfs.datastore", 
          "type": "measure" 
        }, 
        { 
          "child": { 
            "compression": "none", 
            "path": "datastore", 
            "type": "levelds" 
          }, 
          "mountpoint": "/", 
          "prefix": "leveldb.datastore", 
         "type": "measure" 
       } 
], 
     "type": "mount" 
   }, 
   "StorageGCWatermark": 90, 
   "StorageMax": "10GB"             #最大可用存储空间 
}, 
"Discovery": { 
   "MDNS": { 
     "Enabled": true, 
     "Interval": 10 
   } 
}, 
"Experimental": { 
   "FilestoreEnabled": false, 
   "Libp2pStreamMounting": false, 
   "P2pHttpProxy": false, 
   "QUIC": false, 
   "ShardingEnabled": false, 
   "UrlstoreEnabled": false 
}, 
"Gateway": { 
   "APICommands": [], 
   "HTTPHeaders": { 
     "Access-Control-Allow-Headers": [ 
       "X-Requested-With", 
       "Range" 
     ], 
     "Access-Control-Allow-Methods": [ 
       "GET" 
     ], 
     "Access-Control-Allow-Origin": [ 
       "*" 
     ] 
   }, 
   "PathPrefixes": [], 
   "RootRedirect": "", 
   "Writable": false 
}, 
"Identity": { 
   "PeerID": "QmYNYDp5PEi64dgTYRdci3XhtmQEnZVBQTATinWw6fq3Ac", 
"PrivKey": "CAASqQkwggSlAgEAAoIBAQDpF9xJrTde996NuhNmED5Xg90wRqvtMQJtovRcq5o79DldeQeuKe9ket7/+TIs5Cn+QQekwJCClmBWh7e+xNL8RP5Mer0fABw4yAESR8E0PhJhcbI0Wlgh2X18NBFUmri 
IZqzcKedX5MzPa7yFhNoDtGotAmXb9smoVIRZVOg9CqR0xG0RqeFwBZGXCtaeRxK18oFHNwZ3t6G5xycvyeXpYxIoDfqUO7mb7c1g1MTn3gOyUbi4kAZvWAAfdmnPiCEI7nHyhMY0ZOJqaqPh8AOxuVLtcHgPYfRgHU+QMk 
cEHVMzz2Pu41LLS2NWs8i8CjM5N+EBuorndWN2LfEd0xeNAgMBAAECggEAYOpj1FpqCFmFNmZkxG4Cjb6tC/KGb5OOD+nOMm3DLiRoaZ31/ItBFwUjjUiefR3M/AMr22uZakJ+AdxiILaThwJkvYXW9nnEQjOehmxBP6iDW 
fK9Bpl9xW05iJfZkNTX3xbZzpy5rMjcA24nL1jCkQHFl7tEgMXGqO+jK8Vq3l2wSY9z7c/DJwFrtSzJJxk34qgEnlzLA/aNislRDMqP+3CR3x+f/d+rzYof41b77yuWXF20tn2iWYMa7tSKFXPHNzC7CjQw5waKFhcoNni3 
iZ8Snfy6pQuWGmCJqcl+WxnLgVxQNdKgKAPjaXM7kRRAZYUF07+7mElS32BdjlS/3QKBgQDyuqmHIFUZsg/ZMSa4CaCujvlFpQO+7gO1p4R4dS++IY3xD9yNek9kngQb9GPmpMOMKS5cwMNXByuBb5KY2AWC0nOXEizfl90 
zDrXI+SdKxuQhw9/lhGKEAYMij+XM23JsbFQdnDBq8ayt72C0Dt1M9Do/NZdFlDQeLC/YQVYVXwKBgQD11lRhcd1o5Nb229RLo7AHzVkCwO+1TNQMOge42JzpA351fcGKvL+RkVstwCQGdhDEN4F3dJaEGs/6zYuD1dS9zt 
Ym4Zc4lrqwQ3v51MriEEP24E9WjxxO0icbftrrn8iJWJiP/JjAKQZUZhGnqkr6ME8LYPcv3gIUWEBvSYpukwKBgQDydH/YSPSYeSOZiJ4rYPqOwqO97GnEcs1jy1PoWu34ll3JOFXPQChD0g86uTB894GY5J256pZ0vOW5I 
fCmGcnPdlYdxfrq0TATyxLMEAwuhmLkU1q3UThysWwCvwgFTAKMyNxww04d1Q/uodjPorVtI9t2vho/Vx2EMhEMi57oMwKBgQCC8bLoZJomsR2/R8CAuaOdxEdRLCuCSnX4PUC3uMl7ZB0Lv/xDRd5UTzRd3iZSOrkbiuUv 
F67ElvOJB8r0YgV7RJzVAPxnbAHsuUVkAXA/kaJh8YDQ/lF5un6SKrO5JdbPMZ2xtD44vKFeey+UOyTMtsajrPZ9TKeW5psLrARMeQKBgQCbtXDnE0fcJvHGAnbQu5xVWMs6c9fnXBD6U6UN68BbLt2t5X49dce6Ef1KoLX 
D4gIE6Y4GYgBsl7sQHXlJl800XdkhaWFrvzw+9R5/eLEh0XXqts/mOL1R6xnozEvEnVrF+0jecDlw6Fee1X1pB8g1eer7G8odP6uhiGWY3+pOEw==" 
  }, 
  "Ipns": { 
    "RecordLifetime": "", 
    "RepublishPeriod": "", 
    "ResolveCacheSize": 128 
  }, 
  "Mounts": { 
    "FuseAllowOther": false, 
    "IPFS": "/ipfs", 
    "IPNS": "/ipns" 
  }, 
  "Pubsub": { 
    "DisableSigning": false, 
    "Router": "", 
    "StrictSignatureVerification": false 
  },    
  "Reprovider": { 
    "Interval": "12h", 
    "Strategy": "all" 
  },  
  "Routing": { 
    "Type": "dht" 
  },  
  "Swarm": { 
    "AddrFilters": null, 
    "ConnMgr": { 
      "GracePeriod": "20s", 
      "HighWater": 900, 
      "LowWater": 600, 
      "Type": "basic" 
    }, 
    "DisableBandwidthMetrics": false,

    "DisableNatPortMap": false, 
    "DisableRelay": false, 
    "EnableRelayHop": false 
  } 
}

 

九、跨域资源共享CORS配置

IPFS结点上线

ipfs daemon  

为了后续的开发方便,我们还需要对跨域资源共享( CORS )进行配置,ctrl- c退出ipfs,然后按照下面的步骤进行跨域配置(如果加入时出现问题,可以重启服务,在新的SSH窗口配置CORS)。

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["*"]'

ipfs config --json Addresses.API '"/ip4/0.0.0.0/tcp/5001"' 

ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST", "OPTIONS"]' 
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]' 
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Headers '["Authorization"]' 
ipfs config --json API.HTTPHeaders.Access-Control-Expose-Headers '["Location"]'

 

十、配置IPFS服务开机自动启动

1. 创建服务文件

         sudo vim /etc/systemd/system/ipfs.service

内容如下:

[Unit] 
description=ipfs p2p daemon 
After=network.target 
Requires=network.target

[Service] 
ExecStart=/usr/local/bin/ipfs daemon

[Install] 
WantedBy=multi-user.targe

最后,说一下/etc/systemd/system/下的配置文件(XXXX.service), 
其中有三个配置项,[Unit] / [Service] / [Install] 
1) [Unit] 区块:启动顺序与依赖关系。 
2) [Service] 区块:启动行为,如何启动,启动类型。 
3) [Install] 区块,定义如何安装这个配置文件,即怎样做到开机启动。 

2. 服务插入

#给予运行权

sudo chmod +x /etc/systemd/system/ipfs.service

# 重新加载配置文件 
sudo systemctl daemon-reload

# 设置IPFS开机自动启动 

sudo systemctl enable ipfs.service

# 重启服务 
sudo systemctl restart ipfs.service

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/jamenew/article/details/87107142

智能推荐

嵌入式 hi3519平台uboot引导nfs文件系统_嵌入式 nfs引导-程序员宅基地

文章浏览阅读575次。首先贴出来我的bootargs的设置(注没有换行符!!!):setenv bootargs noinitrd mem=64M root=/dev/nfs init=/linuxrc rw nfsroot=10.10.2.59:/opt/rootfs/ ip=10.10.1.156:10.10.2.59:10.10.1.1:255.255.255.0:skdkjzz:eth0:off conso..._嵌入式 nfs引导

硬阈值(Hard Thresholding)函数解读_硬阈值(hard threshold)-程序员宅基地

文章浏览阅读956次。版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。 ..._硬阈值(hard threshold)

计算机研究生各专业方向简介及对应就业方向_计算机研究生方向-程序员宅基地

文章浏览阅读1.8w次,点赞44次,收藏292次。计算机研究生各专业方向简介及对应就业方向(将发布于公众号“保研岛”,现先于博客发布以防侵权)写在前面计算机作为当下热门专业,其下有着多个不同的分支方向,不同的方向涉及不同的知识储备、思维模式及应用领域,每位有意于学习计算机的小可爱有必要了解各个方向的全貌,来找到最适合自己的领域。下面就让岛主来带大家详细了解一下。一、人工智能简介:人工智能是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的科学,是数学、系统学、控制学、计算机科学、认知科学等学科交叉形成的综合性学科特点:当下最_计算机研究生方向

Linux 开源存储全栈详解——从Ceph到容器存储-程序员宅基地

文章浏览阅读1.8k次。//////////////////////在留言区留言说出码农生涯小故事留言点赞前三名,免费送此书截止日期12.30号//////////////////////内容简介本书致力于帮助..._linux开源存储全栈详解

html的map标签的coords确定坐标的方法_coords怎么确定坐标-程序员宅基地

文章浏览阅读5.5k次。当你不是用Dreamweaver来编写html时,又希望快速获得图像区域area的位置坐标,使用Photoshop工具也是一个不错的选择哦,接下来让我们一起来操作一下吧。从简单的方形或者多边形开始,打开ps,打开菜单栏的“窗口”,勾选“信息”接下来鼠标指到方形的对角线点,左上角和右下角,右边的“信息”框会显示,鼠标所指的x,y坐标(x:495像素,y:29像素),coords=“x1,y1,x2,y2”;如果是多边形,同理,鼠标指向多边形的每一个顶点,记录下坐标值,coords=“x._coords怎么确定坐标

Bootstrap4 信息提示框_bootstrap4 通知-程序员宅基地

文章浏览阅读4.3k次。<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> _bootstrap4 通知

随便推点

【CRC算法】CRC算法、原理及程序-程序员宅基地

文章浏览阅读103次。CRC算法及原理 http://www.cnblogs.com/FPGA_DSP/archive/2010/05/08/1730529.html?login=1 CRC算法及原理 CRC校验码的基本思想是利用线性编码理论, 在发送端根据要传送的k位二进制码序列,以一定的规则产生一个校验用的监督码(..._crc,agvrtfcf,,i、‘:、

Ubuntu系统下JDK的安装与配置(一)_sudo add-apt-repository ppa:openjdk-r/ppa-程序员宅基地

文章浏览阅读260次。本文整理了Ubuntu系统下通过ppa源安装、配置JDK的方法。1.添加ppa源ppa源是Ubuntu的一个在线软件仓库,通过apt方式可以访问并安装ppa源中的软件。添加ppa源到本地本地repository,并更新本地repository。sudo add-apt-repository ppa:webupd8team/javasudo apt-get update..._sudo add-apt-repository ppa:openjdk-r/ppa

机器学习 分类问题_机器学习的分类问题-程序员宅基地

文章浏览阅读842次。一.概述1.概念:"分类"(Classification)是指根据已有样本,通过1/多个特征判断新样本属于哪个已知的样本类.也就是说,给出1个训练集{(x1,y1)...(xn,yn)},据此得到1个分类函数,来将新样本xi与某个已知的样本类yi关联起来.分类问题属于有监督学习2.相关算法:贝叶斯定理(Bayes' Theorem)决策树(Decision Tree)K-近邻算法(K-Nearest Neighbours)神经网络(Neural Networks)支持向量机(Suppor_机器学习的分类问题

LinuxCNC-程序员宅基地

文章浏览阅读934次。LinuxCNC(增强型机床控制)是一个计算机控制机床(如铣床和车床)、机器人(如puma和scara)和其他计算机控制机床(多达9个轴)的软件系统。LinuxCNC是具有开放源代码的自由软件。LinuxCNC的当前版本完全根据GNU通用公共许可证和较小的GNU通用公共许可证(GPL和LGPL)进行许可LinuxCNC提供:图形用户界面(实际上有多个界面可供选择)RS-274机床编程语言G代码的解释器一种具有前瞻性的实时运动规划系统低电平机器电子设备(如传感器和电机驱动器)的操作。_linuxcnc

总结2016年国内外的AR/VR产品_ar国外产品-程序员宅基地

文章浏览阅读3.4k次。2017年到了,大家都知道2016年是VR元年,那么去年有什么VR/AR新奇的产品进入了我们的视野,有哪些公司作为开拓者在探索者VR/AR领域,我们一起来总结一下。_ar国外产品

浅谈struts.xml在SSH中的作用_struts.encparams-程序员宅基地

文章浏览阅读1.2k次。struts.xml文件是整个Struts2框架的核心,主要负责管理Struts2框架的业务控制器Action。struts.xml放在根目录下,jsp页面放在WEB-INFO下面的时候,外部是无法直接访问的,只能通过action跳转才能访问,安全性相对而言比较高,能够更好做权限控制,但是后期维护很麻烦,所以建议把jsp放在webContent下面,通过编写过滤器来防止直接访问,后期维护方便。_struts.encparams