猫窝私语 — Makumo's Blog

玛酷猫的温馨小窝,记录生活点点滴滴。

@玛酷猫7月前

02/16
16:33
其他

Ionic 3 升级 Ionic 4 迁移踩坑系列(四)

路由
Ionic4整体舍弃了Ionic3中的使用IonicPage设置路由地址的方法,而完全使用Angular的路由器(虽然在ionic3中也可以使用Angular路由,不过之前项目都是使用Ionic3的路由方法)
在初始化的项目结构目录里src/app/app-routing.module.ts文件,一个简单的结构类似下方:

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { PermissionGuard, WelcomeGuard } from './guard/';

const routes: Routes = [
  { path: '', redirectTo: '/welcome', pathMatch: 'full' },
  { path: '', canActivate: [PermissionGuard], children: [
    { path: 'app', loadChildren: './pages/tabs/tabs.module#TabsPageModule' },
  ]},
  { path: 'welcome', canActivate: [WelcomeGuard], loadChildren: './pages/welcome/welcome.module#WelcomePageModule' },
  { path: 'sign-in', loadChildren: './pages/sign-in/sign-in.module#SignInPageModule' }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule {}

在这个简单结构中包含一个tabs主模块,一个欢迎页,一个登录认证页面。用户第一次访问时,由第一条路由配置导向欢迎页,在欢迎页的配置上有路由守卫(Route guards)的设置,用来判断是否第一次访问,如果不是则引导到主模块,在主模块上同样配置一个路由守卫,用来检验用户权限,如权限不正确则引导到登录页面。此外路由不仅可以配置在总的路由配置文件中,也可以配置在各级子模块中,一方面清晰模块关系,同时也方便模块的添加和移动。路由相关配置也有很多,详情可以参考官方文档,这里是传送门

路由守卫
在Ionic3中,使用ionViewCanEnter和ionViewCanLeave实现Route guards的功能,而在Ionic4中,由于使用Angular的路由,同样也使用其对应的路由接口,在官方文档中,有5种接口,分别是

CanActivate to mediate navigation to a route.
CanActivateChild to mediate navigation to a child route.
CanDeactivate to mediate navigation away from the current route.
Resolve to perform route data retrieval before route activation.
CanLoad to mediate navigation to a feature module loaded asynchronously.

在上面的例子中,使用了两个路由守卫用来判断是否第一次访问和是否具有用户权限,其中判断初次访问的例子如下

import { Injectable } from '@angular/core';
import { Router, CanActivate, RouterStateSnapshot, ActivatedRouteSnapshot } from '@angular/router';
import { Storage } from '@ionic/storage';

@Injectable({
  providedIn: 'root'
})
export class WelcomeGuard implements CanActivate {

  constructor(public router: Router, private storage: Storage) {}

  async canActivate(next: ActivatedRouteSnapshot, state: RouterStateSnapshot): Promise<boolean> {
    const first = await this.storage.get('firstIn');
    if (first) {
      this.router.navigateByUrl('app/tabs/(home:home)');
    }
    return !first;
  }
}

在路由守卫中判断本地存储中是否存在首次访问的标识,有的话就直接进入tabs模块的home子模块。更多详细用法,同样参见官网文档,传送门

Ionic 3 升级 Ionic 4 迁移踩坑系列(四)

@玛酷猫8月前

01/10
14:39
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(三)

接下来就是页面的迁移,先用命令创建原来项目对应的页面,例如登录页面

ionic g page pages/signIn

这是会在src/app/pages目录下面生成sign-in文件夹,里面包含5个文件,相对于Ionic3,除了文件名命名有些许区别外,同时还多了一个测试文件,对比下Ionic3的sign-in.ts和4的sign-in.page.ts文件的主体结构

# ionic3
import { Component, OnInit } from '@angular/core';
@IonicPage({
  segment: 'sign-in'
})
@Component({
  selector: 'page-sign-in',
  templateUrl: 'sign-in.html',
})
export class SignInPage implements OnInit {
  ngOnInit() {}
}

# inoic4
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
@Component({
  selector: 'app-sign-in',
  templateUrl: './sign-in.page.html',
  styleUrls: ['./sign-in.page.scss'],
  encapsulation: ViewEncapsulation.None
})
export class SignInPage implements OnInit {
  ngOnInit() {}
}

整体上差别不大,主要区别在@Component部分,选择器的命名,模板文件和样式文件的引用,3中的@IonicPage部分在4种移除,部分功能被放在Angular的路由中。此外特别提下encapsulation: ViewEncapsulation.None的问题,这部分我也没完全弄明白,大概理解是Ionic4使用了标准的Web Components,可以在页面上看到大量的shadow-dom,默认情况下,由于Angular提供的样式包装机制来封装组件,使得组件的样式不受外部影响,就是说无法修改组件的样式,所以这里要将封装模式调整成none,以便于修改组件的样式,详细说明请参考官方文档,传送门。此外由于使用标准Web Components,样式也要大量的使用CSS4 Variables的写法。

页面生命周期

在Ionic3中,常用的页面生命周期函数有下面6种

  • ionViewDidLoad 当页面加载的时候触发,仅在页面创建的时候触发一次,如果被缓存了,那么下次再打开这个页面则不会触发
  • ionViewWillEnter 当将要进入页面时触发
  • ionViewDidEnter 当进入页面时触发
  • ionViewWillLeave 当将要从页面离开时触发
  • ionViewDidLeave 离开页面时触发
  • ionViewWillUnload 当页面将要销毁同时页面上元素移除时触发

在Ionic4中,使用Angular的生命周期函数,具体ionViewDidLoad被ngOnInit替代,ionViewCanEnter和ionViewCanLeave被路由守卫替代,其他的暂时可以正常使用,不过可能在以后的版本中被其他用法做代替。

组件的标准化

由于使用Web Components标准,很多组件和属性的写法也发生变化,譬如

// ionic 3
<button type="button" ion-button clear small icon-start (click)="findPassword()" class="option-password">忘记密码</button>

<ion-list radio-group no-lines [(ngModel)]="schoolCode">
  <ion-item *ngFor="let s of schools">
    <ion-avatar item-start><img src="{{s.logo}}"></ion-avatar>
    <ion-label>{{s.name}}</ion-label>
    <ion-radio value="{{s.code}}"></ion-radio>
  </ion-item>
</ion-list>

// ionic 4
<ion-button type="button" fill="clear" size="small" (click)="findPassword()" class="option-password">忘记密码</ion-button>

<ion-list lines="none">
  <ion-radio-group [(ngModel)]="schoolCode">
    <ion-item *ngFor="let s of schools">
      <ion-avatar solt="start"><img [src]="s.logo" alt=""></ion-avatar>
      <ion-label>{{s.name}}</ion-label>
      <ion-radio [value]="s.code"></ion-radio>
    </ion-item>
  </ion-radio-group>
</ion-list>

除了button标签替换成ion-button以外,很多属性也发生变化,譬如button的所有属性都进行了更换,clear更换成fill=“clear”等,其他标签的属性,譬如item-start更换为solt=“start”,此外类似radio-group的用法也发生大变化。由于不少用法发生变化,具体还是对应着官方文档进行迁移,传送门

Ionic 3 升级 Ionic 4 迁移踩坑系列(三)

@玛酷猫8月前

01/4
10:59
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(二)

首先是更新NodeJS版本,Angular6要求版本不低于8.X,由于之前安装高版本的nodeJS一直有着不可描述的问题,导致node-sass无法安装,无奈只能安装6.X的版本使用本地文件来强行安装node-sass,不过现在貌似没这个问题了。更新也比较方便,卸掉重新安装就好了。
开启一个新的tab项目,详细的安装可以参考官方文档

ionic start myApp tabs --type=angular

provider迁移
项目建好后,先将原来项目中的provider复制到新项目中,这时候会看到满篇的错误提示,一个一个来调整。
1、storage在Ionic4中不再是默认自带,需要单独安装

npm install --save @ionic/storage

2、换用新的http模块

//ionic3 部分代码
import { Http, Headers, RequestOptions } from '@angular/http';
//……中间其他代码……
const headers = new Headers();
let Token: string = '';
headers.append('Token', Token);
this.options = new RequestOptions({ headers: headers });

//ionic4 部分代码
import { HttpClient, HttpHeaders } from '@angular/common/http';
//……中间其他代码……
const headers = new HttpHeaders();
let Token: string = '';
headers.set('Token', Token);
this.options = { headers };

由于需要和数据服务器API通讯,用户的信息token是存放在请求的header中,在Ionic3中使用的Headers, RequestOptions来处理请求头部,这两个组件在3中也属于不推荐使用的,当时因为还能用,图省事就继续使用了。4种更换为HttpClient、HttpHeaders,和以前方法使用变化不大,调整下就好。

3、调整Components用法,这部分也是整个项目变动最多的地方,几乎所有的Controller都有参数变动和使用方法的变动,想像迁移文档说的那样直接复制进来就能用基本没法实现。举个例子,项目中有个全局的顶部消息提示控件

//ionic3
toast(message: string) {
  this.toastCtrl.create({
    message: message,
    duration: 1500,
    position: 'top'
  }).present();
}

//ionic4
async toast(message: string) {
  const toast = await this.toastCtrl.create({
    message: message,
    duration: 1500,
    position: 'top'
  });
  toast.present();
}

在Ionic3中可以直接创建后接present()来触发使用,而在4中,需要配合async/await来使用。

4、RxJS的调整,官方有个迁移文档,传送门,并且给出了一个迁移工具,不过试了下不是太好用,可能原本的项目写的就不是很规范,只能自动修复一小部分。还是老老实实手动来吧,顺便加深下印象。以下是一个登录的代码片段

//ionic3
import { Observable } from 'rxjs';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
//……中间其他代码……
PostSignIn(request: PostUserSignInRequest): Observable<any> {
  return this.http.post(this.coreService.baseUrl + '/tokens', request)
    .map(res => res.json());
}

//ionic4
import { Observable } from 'rxjs';
import { map, catchError } from 'rxjs/operators';
//……中间其他代码……
PostSignIn(request: PostUserSignInRequest): Observable<any> {
  return this.http.post(this.coreService.baseUrl + '/tokens', request)
  .pipe(map(res => res));
}

首先是引入调整,这个全项目批量替换下就好,然后是原来的链式操作(dot-chained operators)要更换为管道操作(pipeable operators),简单点说就是将原先所有的.xxx操作全部放置到pipe()这个方法中,其他的用法项目中用到的少,可以去查看官方文档。

Ionic 3 升级 Ionic 4 迁移踩坑系列(二)

@玛酷猫8月前

01/3
23:01
WordPress 建站日志

小窝加装泛域名SSL证书

(本来打算写在上篇的,篇幅有点长,干脆拆成两篇好了)
书接上回,话说随着chrome的版本更新,所有的http访问的网站都会在网址前面标一个大大的不安全,这都9102年了,不给网站弄的SSL证书也太不像话了。免费证书哪家强,当然是选择Let’s Encrypt,而且今年去年年中的时候已经支持泛域名的证书,B格更高,同时也推出了新的申请方式,相对于以前单个域名的申请,方便很多。

首先要下载acme.sh,安装成功后断开重新连接下终端,要不会后续的命令提示找不到

curl https://get.acme.sh | sh

由于acme.sh可以自动配置DNS,这就需要获取到域名的API,我的域名是使用DNSPOD解析的,这里就用DNSPOD做例子,其他的请参考官方指南。登录DNSPOD,在控制台——用户中心——安全设置里面,启用API Token,创建新的API Token,这里一定要保存好Token,因为这个是只显示一次,关掉后就没法获取完整,只能删掉重新建,同时记下Token对应的ID,然后运行下面命令,等待120秒验证,屏幕上会显示倒计时,如果一切正常的话,屏幕会显示申请成功并显示4个证书文件的路径。

export DP_Id='ID数字'
export DP_Key='Token字符串'
acme.sh --issue -d makumo.com -d *.makumo.com --dns dns_dp

然后打开站点的Nginx的配置文件,添加相关的配置,例如:

server 
    {
        listen 443 http2 ssl;
        server_name makumo.com;
        index index.html index.php;
        root  站点目录;
        ssl_certificate /root/.acme.sh/makumo.com/fullchain.cer;
        ssl_certificate_key /root/.acme.sh/makumo.com/makumo.com.key;
        ssl_trusted_certificate  /root/.acme.sh/makumo.com/ca.cer;
        include proxy-pass-php.conf;
        location ~ .*\.(gif|jpg|jpeg|png|bmp|swf)$
        {
            expires      30d;
        }
        location ~ .*\.(js|css)?$
        {
            expires      12h;
        }
        location ~ /\.
        {
            deny all;
        }
}

proxy-pass-php.conf文件即为上一篇中的关于转发到Apache的部分.

nginx -s reload

重新加载Nginx配置文件就能使用https访问站点,这时候还会存在几个问题,站点中图片、脚本、样式还是使用的http来引入,在浏览器中会报出错误,后台无法进入,浏览器会显示过多的重定向,网络里面会看到一堆的302重定向,搜了下,绝大部分都会说在Wordpress配置文件中添加开启SSL的配置,如下:

$_SERVER['HTTPS'] = 'on';
define('FORCE_SSL_LOGIN', true);
define('FORCE_SSL_ADMIN', true);

但是我这么设置后,前台没问题了,后台还是无法进入,虽然不报过多的重定向,直接报403错误了。
搜素了半天,还在有更简便的解决方案,安装插件really-simple-ssl,一次性解决各种恶心的问题。
另外,由于站点使用七牛作为图片的CDN缓存,站点切换为https后也需要将七牛的CDN改成https模式,在七牛的后台添加下证书(之前申请证书的4个文件,fullchain.cer是证书,域名.key就是对应的密钥),关联域名开启SSL就好了,这也是泛域名证书的方便之处,不用再次申请单域名证书了。七牛的https是收费的,看了下,0.28元/G,之前还有赠送的10元余额。应该能用段时间。

小窝加装泛域名SSL证书

@玛酷猫8月前

01/3
22:08
建站日志

小窝迁移升级

今天忽然收到阿里云的提示,个人的云服务器要到期了,连忙登录上去准备续费,一看价格,我勒个擦,8XX,当初买的时候才3XX,去年续费的时候5XX,这涨的也太快了,看了下新购,同样配置同一地区也才5XX,算了算了,还是重新购买台好了,虽然要重新配环境迁移网站麻烦点,谁让咱穷呢。

下单付款,等会就开通,ssh连上去,先配置下环境,之前那台服务器用的lnmp一键包,当初菜鸟一只啥都不会。现在基本了解了后,一键包方便是方便,但是问题也不少,首先就是文件的安装位置都变了,配置文件也和默认的不太一样,详细配置的时候各种别扭,其次就是带着一些不用的软件,还有就是版本升级的问题。所以还是自己配好了,好在CentOS配置起来比较简单,几行命令就好了。服务结构还是像往常那样,Nginx跑静态文件和代理,Apache跑PHP7,预配NodeJS和Ruby,平时做简单的调试用,通过Nginx转发访问

# 安装nginx
yum install nginx
# 由于yum源没有php7,所以要更换
yum install epel-release
rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
# 安装php7.2以及相关扩展
yum install php72w php72w-cli php72w-common php72w-devel php72w-embedded php72w-fpm php72w-gd php72w-mbstring php72w-mysqlnd php72w-opcache php72w-pdo php72w-xml
# 安装mariadb
yum install mariadb mariadb-server
# 设置mariadb密码,需要先运行mariadb服务
mysql_secure_installation

新建站点和相关配置就不多说了,有几点要注意下,
1、httpd的默认配置文件里面,所有请求会全部拒绝,要删掉或者注释掉

<Directory />
    Options FollowSymLinks
    AllowOverride none
    Require all denied
</Directory>

2、站点的目录用户组要调整成为apache:apache

httpd服务的端口调整为88,在Nginx站点配置的时候,添加相关的配置说明,如下例子

location /
{
    try_files $uri @apache;
}
location @apache
{
    internal;
    proxy_pass http://127.0.0.1:88;
    include proxy.conf;
}

location ~ [^/]\.php(/|$)
{
    proxy_pass http://127.0.0.1:88;
    include proxy.conf;
}

proxy.conf里面存放一些代理设置

proxy_connect_timeout 300s;
proxy_send_timeout   900;
proxy_read_timeout   900;
proxy_buffer_size    32k;
proxy_buffers     4 32k;
proxy_busy_buffers_size 64k;
proxy_redirect     off;
proxy_hide_header  Vary;
proxy_set_header   Accept-Encoding '';
proxy_set_header   Host   $http_host;
proxy_set_header   Referer $http_referer;
proxy_set_header   Cookie $http_cookie;
proxy_set_header   X-Real-IP  $remote_addr;
proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header   X-Forwarded-Proto $scheme;

最后迁移站点文件、还原数据库,启动各服务并设置随系统启动,测试没问题后将域名切换过来就ok了。

systemctl enable nginx.service
systemctl enable httpd.service
systemctl enable maridb.service
systemctl start nginx.service
systemctl start httpd.service
systemctl start maridb.service

顺便一提的是本次迁移也干掉的www,www是个很奇怪的历史遗留的问题,这是个二级域名,可能很多人认为方便呀,直接ctrl+enter就自动补全了,可是最早的IE浏览器直接ctrl+enter的话补全的是www.xxx.cn.co而并不是www.xxx.com,方便无从谈起,直到后续大量的国产带壳浏览器的出现才修正过来,况且那时候.net域名还是很流行的,还有不少.cn的域名,而且大部分人都不会直接打域名来访问网站,基本上都是打开百度搜索网站,要不就是收藏夹或者聚合网址来上网。所以www就是多余的,去掉后网址还精简一些。虽然去掉www会影响搜索引擎的搜录,好在小窝文章本来就不多,写的也是断断续续的,大部分都是方便自己以后查找用的,也不在乎那点收录了。

小窝迁移升级

@玛酷猫9月前

12/28
16:31
Ionic(Angular)

Ionic 3 升级 Ionic 4 迁移踩坑系列(一)

Angular今年的发展真是快,去年年底5刚刚发布,年中就发布6,到年底7也来了,大版本的升级也导致它的很多组件也随之升级,慢慢的放弃了对低版本的支持,这对于使用基于Angular的Ionic开发的本人来说就是件很郁闷的事情。之前一直使用Ionic 3开发项目,还是基于Angular5的,年中的时候本地开发环境更新组件没注意,直接把Angular升级到6了,然后可想而知,项目直接跑不起来了。还原package.json后每次更新组件都检查下版本,避免错误升级,很是麻烦。随着Ionic4的测试版本不断的更新,Ionic cli动不动就提示更新Ionic4,稍不留神就傻逼,再加上越来越多的组件默认使用Angular 6,主要是其中RxJS的语法变动很大,导致没法向下兼容5,这也将Ionic升级到4的想法提上日程。毕竟ios和android还在不停的更新版本,每次更新或多或少都会出现兼容性问题,组件导致的兼容性问题主要还是靠组件作者更新,虽然可以自己fork一个分支处理,毕竟费时费力。

去Ionic官网翻了翻迁移指南,官方写的实在是太简单,全文如下:

  1. Generate a new project using the blank starter (see Starting an App)
  2. Copy any Angular services from src/providers to src/app/services
    • Services should include { providedIn: ‘root’ } in the @Injectable() decorator. For details, please see Angular provider docs.
  3. Copy the app’s other root level items (pipes, components, etc) keeping in mind that the directory structure changes from src/components to src/app/components, etc.
  4. Copy global Sass styling from src/app/app.scss to src/global.scss
  5. Copy the rest of the application, page by page or feature by feature, keeping the following items in mind:
    • Emulated Shadow DOM is turned on by default
    • Page/component Sass should no longer be wrapped in the page/component tag and should use Angular’s styleUrls option of the @Component decorator
    • RxJS has been updated from v5 to v6 (see RxJS Changes)
    • Certain lifecycle hooks should be replaced by Angular’s hooks (see Lifecycle Events)
    • Markup changes may be required (migration tool available, see Markup Changes)

In many cases, using the Ionic CLI to generate a new object and then copying the code also works very well.

大概意思就是用命令新建一个空的项目,将原来项目各个部分拷贝进来,注意4的路径有所调整。服务的声明有所调整、全局样式文件不一样、RxJS请自己看升级文档、页面生命周期时间沿用Angular。看来不麻烦呀,于是乎我就傻呵呵的按着文档操作一顿后,都不用试跑的,IDE上满屏幕的红色波浪线(各种错误)仿佛在嘲笑。看了看IDE上面提示的各种错误,连最基本的ionic、angular的引用方式都有所变化,我就不信有人能按照这个智障的迁移文档,把项目跑起来。尤其是看到文档最后一句话:“In many cases, using the Ionic CLI to generate a new object and then copying the code also works very well. ”,还信誓旦旦的说大部分情况下按照这个操作项目都能跑起来,我&……¥&*……&#,还是老老实实一个模块一个页面的迁移好了。

经历的大半个月的迁移工作,虽说还没有完全结束,迁移过程中踩的坑可真不少,准备做一个系列来写了。一方面记录下的这些问题,方便以后查看,另一方面也希望帮助其他的人,毕竟目前在国内,相对于React和Vue,Angular还太小众,各种文档和解决方案都很少,遇到问题都要爬google搜索,要不就去啃官方论坛和stackoverflow。

随带一提的是Ionic(Angular)的发展简直是坑神一样的存在,当年AngularJs升级Angular(ionic1到2)的时候,惊呼上当受骗,本以为是个版本升级,能迁移的时候菜发现这明明就是两种不同的东西,没办法相当于重新学了一遍,ionic2/3到4又相当于再重学一边,4为了更标准化web component,修正了以前版本各种不标准的用法和属性,而且可以说不在依赖框架,也就是说以前Ionic和Angular是捆绑在一起的,从4版本开始,也可以使用React和Vue来做开发,更加灵活。并且使用标准化的web component后,以后也不会出现类似1到2、2/3到4这种痛苦的迁移过程了,应该会很平滑的升级,版本迭代的速度应该会更快。

Ionic 3 升级 Ionic 4 迁移踩坑系列(一)

@玛酷猫1年前

03/23
15:12
Ruby

Rails5踩坑系列——Vagrant和NFS共享文件夹

新年新项目,被老项目折腾大半年后,部门一直认为新项目要脱离老的Rails3.2版本,拥抱新版本。先准备前期环境,对应的安装了最新的Ruby2.5和Rails5.1.5,开始项目后台框架搭建工作。同事用vm搭建的虚拟机环境,没啥问题,我是用的Vagrant搭建的虚拟机环境,由于Vagrant自身共享模式很慢,一直配置着vagrant-winnfsd插件使用NFS来做文件共享,速度是快很多,就是经常性会遇到I/O错误,关掉日志防止频繁写入共享盘就好了。新项目跑起来就开始报错,报错信息类似如下

Errno::EEXIST at / File exists @ dir_s_mkdir - tmp/cache/assets/sprockets/v3.0/jG

网上搜了一下,发现一篇博文说到这个,传送门,大体意思就是NFS是大小写不明感,rails在运行中会将assets生成静态文件缓存,存在tmp/cache/assets/sprockets/v3.0/ 目录中,文件按照前两位字母建立文件夹归档,这时候就会遇到类似jg、JG、jG、Jg属于4个不同文件夹,但是NFS大小写不明感,就会认为是一个,在创建的时候就会返回文件夹已存在的问题,文中给出的方案是修改配置文件,将这个文件移出共享文件夹。由于不想将虚拟机原始文件系统里面放置额外的文件,这个方案被我否定了。查了下原来项目里面老版本文件缓存情况,类似的结构和生成方式,不过生成的文件缓存文件名都是大写,文件夹也都是大写,就不存在大小写的问题。本想找办法对应修改下,翻了下Asset Pipeline相关文档和sprockets的相关配置,都没有找到,遂放弃这个办法。在查看文档中,有关于静态资源文件缓存的存储方式的说明,默认似乎是文件方式,文档给出的修改例子是内存方式,于是在development.rb中添加这个配置,重启项目,一切OK。下面的禁用方式也试了下,影响速度还是很明显,同样不考虑。

此外上述文中还提到了其他几种由于NFS大小写不明感而引起的问题以及处理办法,目前暂时还没遇到。下次遇到了也心里有数了。

Rails5踩坑系列——Vagrant和NFS共享文件夹

@玛酷猫2年前

01/19
11:30
心情点滴

码农的35岁总结

岁月如梭,转眼间,一年已逝,都说码农35岁是个坎,回望一年,也是坎坎坷坷,有峰有谷。上半年悠闲下坡,下半年小跑上坡,总体来说,还是要比年初站得更高一些,也收获了不少。梳理梳理,记个流水账,也好给下一年立个标杆,至少不能做的更差吧。

上半年可以用乱七八糟来形容,公司几个领导意见分歧,项目也处于停摆状态,天天也不过是混日子罢了。待到五一,上层终于决定放弃线上部分,我们技术部门也理所当然的被裁员了。现在想想年初就应该选择离开的,与其无所事事在那边耗着,浪费时间精力,真不如离开调整调整。五月份调整了一个月,尤其是锻炼了一个月,整个精神状态恢复了不少,不再像前几个月那样浑浑噩噩的,另外一点额外收获就是熟练骑自行车,也多亏共享单车的火速普及。

六月份来到新的单位,正式开启了下半年提升之路。新公司第一个挑战就是开发语言,公司项目是用ruby on rails开发的,而我对于这个仅限于知道怎么读,幸好这么多年的开发经验在,了解摸索了2周,基本能上手开始改现有的功能,一个月后可以开始做新功能,这期间和同事一直在踩坑,原来项目里面各种坑,服务器部署各种坑,两个人踩得其乐无穷。越来越觉得编程就是理解开发思想,语言只是实现的一种方式而已,只要理解开发思路,用什么语言其实区别都不大。只要理解一种开发语言,学习其他的开发语言并不是很困难的事情。当然,如果想精通的话还需要沉浸其中多年才行。随着项目日趋完善,手机版的项目也提上了日程,考虑到现有团队情况,独立配备开发人员显然不太现实,讨论后决定使用hybird方式开发,由于去年曾用过angularJs(1.x)做过移动版项目,手机版的项目就决定还是用angular开发,最后决定使用angular(4.x+)的一个框架ionic和cordova一起开发,版本都启用最近的版本。刚开始就发现自己被自己坑了,angularJs(1.x)和angular(4.x+)完全就是两个东西,angular2.0+版决定推倒重写,以前掌握的1.x的知识大部分都用不上了。没办法硬着头皮啃新的,好在并不是太多复杂,仿照一个开源的项目,一点一点实现自己项目的功能,2周时间第一个web版就出来了,又花了一周搞定安卓版的编译签名,苹果版的稍微费了点功夫,申请开发者账号,折腾mac环境,xcode编译提交过审等等,苹果开发的坑真不少,好在都一一踩过了。后续又陆陆续续更新不少功能,迭代了6、7个大版本。等过完年重新设计下界面,作为一个新的大版本正式推广。

新的一年,准备多花点时间研究下nodeJs相关,毕竟在弄ionic的时候踩了不少nodeJs的坑,这方面还是要了解下,计划用javascript同时开发前后台做个小项目出来。此外,去年一整年就读了半本《上帝掷骰子吗——量子物理史话》,还没读完。看来读书习惯还是没有养成。今年除了完成去年的书籍,就加读一本书作为目标好了。锻炼身体还要坚持,去年初体检,各项指标都压线,再加上年底一位同窗突然去世,顿时感觉人到中年,身体是第一位的,其他都是扯淡,去年一年减了30斤,还是有点小成果的,今年再接再厉,再减40斤,回到一个比较合理的体重。

懒癌晚期这个问题看来是比较难解决了。一年博客更新寥寥,多次想记录下心得,每次也就写了个标题开了个头,然后就放那了,过段时日也不知道该写什么了,后台可见好几个草稿。估计懒癌还是比较难治愈的,看看今年有什么突破吧,哈哈。

码农的35岁总结

@玛酷猫2年前

11/3
10:46
Ionic(Angular)

Ionic3应用中添加Faye功能

公司rails项目中通过Faye来实现一个简单的好友聊天互动的功能,移动端需要开发简易的教师上课点名的小功能,想想正好可以利用Faye服务来实现,具体逻辑很简单,在课程页面,教师点击点名模块,设置密钥后进入点名页面,通过Faye发布该课程点名信息,学生接收到点名信息后在页面上显示签到按钮,学生点击签到按钮输入密钥,通过Faye服务传递到教师点名页面上,时时反馈签到情况,最后教师通过关闭按钮结束签到并通过Faye告知所有学生,学生页面隐藏签到按钮。

逻辑理顺了,页面搭建完毕,加入Faye犯难了,官方文档只是简单写了下浏览器端如何使用,引入Faye服务端js,然后可以使用subscribe和publish来发布和接受了。在Ionic3项目里面就傻眼了,第一步引入js就不知道咋搞了,网上翻资料,绝大部分都是使用ionic 1.x的资料,度娘里面居然还掺杂一大堆王菲的搜索页面。。。谷歌研究了半天,参考了一篇关于ionic3部署socket.io的文章,终于搞定。

首先还是安装Faye组件

npm install faye --save

新建一个服务provider,初始化同时把相关的推送接收用法写进去

import { Injectable } from '@angular/core';
import * as Faye from 'faye'

@Injectable()

export class FayeService {
  clientUrl: string;
  data: any;
  client: any;

  constructor() {
    this.clientUrl = 'https://your website/faye';
    this.data = null;
    this.client = new Faye.Client(this.clientUrl)
  }

  subscript(callback:any, channelName:string){
    this.client.subscribe('/' + channelName, function (data) {
      callback(data);
      // console.log('receiced data:'+data);
    })
  }

  publish(channelName:string, data:any){
    let publication = this.client.publish('/' + channelName, data);
    publication.then(function() {
    }, function(error) {
      console.log('There was a problem: ' + error.message);
    });
  }

}

最后在app.module.ts中引入这个provider并声明下就可以在项目中使用了。

此外还有一点,由于项目的browser版和接口都启用的ssl,直接使用http://your website:8080/faye 会报错,提示在ssl下访问非ssl存在安全问题balabala之类的,这个需要在nginx中设置端口转发。

在nginx的接口配置文件中添加faye的upstream

upstream faye-socket{
    server 127.0.0.1:8080;
}

接着在配置443的server下面添加转发规则

location /faye {
	proxy_pass http://faye-socket;

	proxy_http_version 1.1;
	proxy_set_header X-Real-IP $remote_addr;
	proxy_set_header Host $host;
	proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

	proxy_set_header Upgrade $http_upgrade;
	proxy_set_header Connection "upgrade";
	proxy_cache_bypass $http_upgrade; 
}

保存后重新加载nginx配置即可。

nginx -s reload

Ionic3应用中添加Faye功能

@玛酷猫2年前

06/24
22:45
Ruby Linux

用Vagrant和VirtualBox搭建Windows下的Ruby on Rails 开发环境

PS:做个系列,记录下各个知识点,方便以后回顾查询,就叫Ruby:从入门到放弃好了(大雾)。

虽然都推荐在类Unix环境上面做Ruby的开发,更贴近于真实服务器的环境,同时也不会遇到各种Windows上奇葩的坑,不过考虑类Unix也同样存在学习成本,并不是主要学习方向,同时也需要在Windows下跑其他一些应用,比如游戏什么的,经过搜索娘的指引,选取这种折中的方法,在Windows平台下使用虚拟机跑类Unix系统。

首先还是安装对应的一系列软件了:

差不多就这么多吧,乱七八糟都装好后就开始配置了。
在工作目录新建一个文件夹,比如Ruby_project,win+x进入命令提示符,使用cd命令进入刚刚建立的文件夹,然后用下面命令配置

#添加box到vagrant列表,比如box存放在d盘根目录
vagrant box add centos7 vagrant-centos-7.2.box
#初始化,会在目录下生成Vagrantfile的配置文件
vagrant init centos7
#启用
vagrant up
#关闭虚拟机命令
vagrant halt
#重启虚拟机命令
vagrant reload

启动起来后,虚拟机会挂载Ruby_project到虚拟机的vagrant目录下面,这时候用secureCrt连接虚拟机,账号密码都是vagrant,root密码同样是vagrant
由于没有单独配置虚拟机的IP地址,默认虚拟机也会使用127.0.0.1来访问,这需要配置下Vagrant的环境,将访问端口映射到虚拟机上,编辑目录下面的Vagrantfile文件,加入下面的端口配置,整体文件看起来像这样

Vagrant.configure("2") do |config|
 config.vm.box = "centos7"
 config.vm.hostname = "dev"
 config.vm.network "forwarded_port", guest: 3000, host: 3000
 config.vm.network "forwarded_port", guest: 80, host: 8080
end

Rails端口使用3000,Nginx的80端口映射到本机的8080端口。其实单独配置IP更方便一些,以后端口一多,一个一个配置很麻烦。
重启后登录虚拟机,开始配置虚拟机的Rails环境

#更新yum
yum update
#安装EPEL
yum install epel-release&nbsp;
yum repolist
#安装依赖库
yum install curl-devel nano sqlite-devel libyaml-devel
#安装RVM,安装指定版本的Ruby
gpg --keyserver hkp://keys.gnupg.net --recv-keys D39DC0E3
curl -L https://get.rvm.io | bash -s stable
source /etc/profile.d/rvm.sh #set up system environment for Ruby, 这步不可少
rvm reload
rvm install 2.0.0 #这里指定ruby版本
#由于众所周知的原因,修改gem的源
gem source -r https://rubygems.org/
gem source -a https://gem.ruby-china.org
#安装nodeJs作为JavaScript的运行环境
yum install nodejs
#安装指定版本的rails
gem install bundler
gem install rails -v 3.2.12 
#安装nginx
yum install nginx

到这里虚拟机环境基本配置完毕了,其他各个插件根据各个项目中的Gemfile在bundle install中进行安装和调整。
在vagrant目录下,输入以下代码

#新建一个项目
rails new hello_world
#进入项目目录
cd hello_world
#检查并安装对于的gem
bundle install
#启动项目
rails s

打开浏览器,输入127.0.0.1:3000 就能看到rails的默认欢迎页了。

启动RubyMine,在之前Ruby_project目录下会出现hello_world的项目目录,直接用RubyMine打开这个文件夹,就能看到该项目的具体源码,这样在IDE中的源码修改会直接作用于虚拟机上。

PS:在Windows下使用Vagrant存在一个问题,就是由于VirtualBox虚拟机的共享文件机制的I/O问题,项目跑起来后,在浏览器浏览很非常的慢,从日志上面看各种资源的读取时间都是几十甚至几百毫秒。网上都说更改共享方式,使用nfsd方式,不过我改过后无法挂载共享盘。问题还没有彻底解决。准备换种共享模式,虚拟机共享目录,本机连接虚拟机的共享目录,这样项目实质是存在虚拟机上,避免I/O的缓慢问题,IDE读取文件慢可以接受,毕竟不会一次打开很多页面。

用Vagrant和VirtualBox搭建Windows下的Ruby on Rails 开发环境