0%

场景

当发生了用户被点赞、评论、关注等操作时,需要由服务器向用户实时地推送一条消息。

实现方式

  • 后台Node.js

    后端推送消息的处理流程

  • 在 Node 服务器建立一个用户信息和 socket id 的映射表,因为同一用户可能打开了多个页面,所以他的 socket id 可能存在多个值。当用户建立连接时,往其中添加值;用户断开连接后,删除相应值。

  • 当 Java 后台存在需要推送的消息时,会向 Node 服务器的 /api 路径 post 一条消息,其中包括用于标识用户的 tokenId 和其它数据。

  • Node 服务器接收到 post 请求后,对请求内容进行处理。根据 tokenId 找出与该用户对应的 socket id,socket.io 会根据 id 来向用户推送消息。

对用户信息的处理

方便起见,这里只用一个数组保存用户信息,实际工作中可以根据需要放入数据库中保存。

1
global.users = []; // 记录下登录用户的tokenId, socketId

当用户登录时,client 会向 server 发送 user_login 事件,服务器接收到后会做如下操作:

1
2
3
4
socket.on('user_login', function(info) {
const { tokenId, userId, socketId } = info;
addSocketId(users, { tokenId, socketId, userId });
})

addSocketId() 会向 users 数组中添加用户信息,不同用户通过 tokenId 进行区分,每个用户有一个 socketIds 数组,保存可能存在的多个 socketId。该函数的具体代码可见 src/utils.js 文件。

同理,还有一个 deleteSocketId() 函数用于删除用户信息,代码可见同一文件。

在获取了用户的 tokenId 之后,就需要找到对应的 socketId,然后向特定用户推送消息。

1
2
3
4
5
// 只向 id = socketId 的这一连接发送消息
io.sockets.to(socketId).emit('receive_message', {
entityType,
data
});

服务器的思路大致如此,接下来介绍客户端中是如何进行相应的处理的。

客户端

Socket.io 的初始化
首先在 html 文件中引入 Socket.io 的 client 端文件,例如通过 CDN 引入:

1
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>

其它的引入方式:

1
2
3
const io = require('socket.io-client');
// or with import syntax
import io from 'socket.io-client';

引入 Socket.io 后就获得了 io 函数,通过它来与消息推送服务器建立连接。

1
2
3
4
5
6
7
// 假设你将 Node 服务器部署后的地址为:https://www.example.com/ws
// 则: WS_HOST = 'https://www.example.com'

const msgSocket = io(`${WS_HOST}`, {
secure: true,
path: '/ws/socket.io'
});

如果监听本地:

1
const msgSocket = io('http://localhost:4001');

这里如果写成 io(‘https://www.example.com/ws') 会出现错误,需要将 /ws 写入path中。

为了能在其它文件使用这一变量,可将 msgSocket 作为一个全局变量:

1
window.msgSocket = msgSocket;

用户建立连接

// 用户登录时,向服务器发送用户的信息。服务器会在收到信息后建立 socket 与用户的映射。
msgSocket.emit(‘user_login’, {
userId,
socketId: msgSocket.id,
tokenId
});

##demo
[demo博文原文](https://segmentfault.com/a/1190000010974426)
[demo](https://github.com/noiron/socket-message-push)
##资料
[socket-io官网](https://socket.io/get-started/chat/)

tailWindCss

需求

写React 项目 有个痛点,有时候想拷贝个已有的js文件,因为有样式,但是现在基本主流都是cssModule ,所以还得拷贝个xx.less文件之类.做Vue开发也是,如果写.vue文件,本来文件就挺长,代码要用鼠标滚轮一直滚看,还要写style部分,又是一坨代码.看着文件一长个人就有点不舒服.

救星

最近看到tailwincss,感觉基本解决了这个痛点.可以参考这篇文章

场景

  • CAS
    • 多个应用共用一个登陆设置.
    • 我现在做的前后端分离的,不用关注权限问题,最后部署时候统一设置单点登陆就可以
  • 手机端不适合基于session的场景,看了jwt方案.
    • 现在好像auth2.0的方案也挺流行,之前工作中主要是用这个实现客户权限控制,最近感觉主要是感觉想微博登陆账号这种不用直接提过密码就可以授权的方案中.

注意以下实现主要是基于python django drf.

CAS方案

单点登陆服务端:server django-mama-cas
客户端:django-cas-ng
测试
  • 如果不加CAS_ADMIN_PREFIX,登陆/admin/会跳转,加上就/auth/test/ 这个测试

非session方案

sso rest风格
  • django-rest-auth demo 也是在rest-framework-tutorial ,然后放在了gitte上面.
  • 测试
    官方代码自己集成了swagger测试

REST framework JWT Auth

  • 测试
    参考官网
  • JWT 配置
    比如 JWT_RESPONSE_PAYLOAD_HANDLER 可以重写然后配置
    # urls.py
    from rest_framework_jwt.views import obtain_jwt_token
    urlpatterns = [
    url(r'^authorizations/>, obtain_jwt_token),
    ]
    # utils.py
    def jwt_response_payload_handler(token, user=None, request=None):
    """
    自定义jwt认证成功返回数据
    """
    return {
    'token': token,
    'user_id': user.id,
    'username': user.username
    }
    # 修改配置 # JWT
    JWT_AUTH = {
    'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1),    'JWT_RESPONSE_PAYLOAD_HANDLER':'users.utils.jwt_response_payload_handler',
    }

参考

今天在配置hyper的时候说可以反向从linux的子系统使用win安装的命令,然后发现得需要升级内核系统,升级预览版preview后后发现win10加了好些功能,逐渐向mac系统靠拢。。。。作为个折腾党来说,虽然不怎么能用到。。。但是还是挺乐此不疲的。

WSL

其他功能,感觉挺好用的几个

参考\

NativeBase 个人感觉资料等在开源的react-native组件库中算是比较出色的,官网还提供了不少集成其他状态管理,路由的demo.查资料没有看到过关于他V2版本的主题相关的中文说明,他官网感觉说的也不直白.大概按我的理解说一下他的自定义主题配置

NativeBase Customizer

官网有提供可视化主题颜色配置页面,设置完颜色后,下载variables.js .可以下载单个组件的,也可以设置全部的.

Theme and Variables

运行 node node_modules/native-base/ejectTheme.js 将nb的主题配置暴露到native-base-theme,包含俩个目录

components: Theme styling files for all the NativeBase components. This is where you would change the style properties of the components if you need to.

Example, if you need to change the height of Button component, you’ll need to change height in native-base-theme/components/Button.js.

variables: Contains three preset theme variable files, namely Platform, material, commonColor. You can change the variables (for color, fontFamily, iconFamily etc) for a uniform look and feel throughout your app.

Set Up

官网提供的下面的这个例子,Platform,Material,CommonColor,从variables目录里面选择一个官方提供了默认三套主题,可以修改一下对应js的变量,参考Theme variables Cheat sheet设置.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import React, { Component } from 'react';
import { Container, Content, Text, StyleProvider } from 'native-base';
import getTheme from './native-base-theme/components';
import material from './native-base-theme/variables/material';
export default class ThemeExample extends Component {
render() {
return (
<StyleProvider style={getTheme(material)}>
<Container>
<Content>
<Text>
I have changed the text color.
</Text>
</Content>
</Container>
</StyleProvider>
);
}
}

Theme Color

Theme Font

可选择字体

Button

  • With Variables
    比如修改Button样式,可以从可视化修改页面下载variable.js,然后结合下面配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    import React, { Component } from 'react';
    import { Container, Content, Button, Text, StyleProvider } from 'native-base';

    import React, { Component } from 'react';
    import { Container, Content, Button, Text, getTheme, StyleProvider } from 'native-base';
    // 从可视化网站下载
    import customVariables from './Themes/variable';
    // buttonTheme is the customized theme of Button Component​,
    // 我理解就是native-base-theme/components下面找对应的js
    import buttonTheme from './Themes/buttonTheme';
    // getTheme is default theme of NativeBase Components
    // customVariables is customized variables used in the components theme
    export default class ThemeButtonExample extends Component {
    render() {
    return (
    <Container>
    <Content>
    <StyleProvider style={buttonTheme(customVariables)}>
    <Button primary>
    <Text> Primary </Text>
    </Button>
    <Button success>
    <Text> Success </Text>
    </Button>
    <Button info>
    <Text> Info </Text>
    </Button>
    <Button warning>
    <Text> Warning </Text>
    </Button>
    <Button danger>
    <Text> Danger </Text>
    </Button>
    <Button small>
    <Text> Small </Text>
    </Button>
    <Button>
    <Text> Default </Text>
    </Button>
    <Button large>
    <Text> Large </Text>
    </Button>
    </StyleProvider>
    </Content>
    </Container>
    );
    }
    }

Theme Your Custom Component

可是结合官方的 StyleSheet 提供的styles ,可以覆盖,如果冲突? 这个有覆盖这个还没具体测试,yourTheme感觉也是可以随便写,
CustomComponent就是你写的这个组件的给的命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import React, { Component } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { connectStyle } from 'native-base';
class CustomComponent extends Component {
render() {
// connect styles to props.style defined by the theme
const styles = this.props.style;
return (
<View style={styles.container}>
<Text style={styles.textContent}>
Your Component with static style
</Text>
</View>
);
}
}
const styles = {
container: {
flex: 1,
backgroundColor: 'green',
},
textContent: {
fontSize: 20,
color: 'red',
},
};
// connect the component to the theme
export default connectStyle('yourTheme.CustomComponent', styles)(CustomComponent);

最近又接触了油猴,可以定制化网站.比如去掉广告啦,排版文字加空格啦.

Tampermonkey

类似的插件有好几个,然后其中最出名的我看的是Tampermonkey.他有几个优势.

  • 备份,在[实用工具]选项卡里面有几个选项,我是用的google cloud .试了一下还挺方便.不过他这个是增量的.可能需要删除一下重复,恢复的时候.
  • firefox ,chrome 都支持.不过听说chrome以后会禁用修改网页之类的.还是有风险的.不好的油猴插件有可能监控你的行为之类的.因为油猴脚本的灵活性和无限可能,不安全的油猴脚本是很危险的。比如它可以在你登录的账号页面上搜集信息,发送到后台,甚至直接下单,修改地址等等
  • 脚本站点(论坛):
  • 现在想着是多看看人家怎么做的.然后就看了几个插件的源码.
  • 没有找到好的教程…
Userscript+ : 显示当前网站所有可用的UserJS脚本 Jaeger

我看的这个的githhub有源码,

  • 依赖
    • iframejs 向iframe里面注入内如
1
2
3
4
5
// 加载依赖js库
ljs.exec(['jQuery', 'iframe', 'psl'], function () {
var fu = new FetchUserjs();
fu.render();
});
  • 本地调试vue组件.

    主要是想弄明白他怎么单独用vue组件的..有点理解的似是而非…….跟之前理解的单独用vue组件感觉有点不一样.这个有点高端.相等于在一个页面中注入一个vue组件使用逻辑.先在frame里面注入html框架.然后再运行打包的vue组件js.要是我自己用webpack是实现的话感觉只有抄的水平..

下载代码后.启动 npm run watch:ui 在dist目录生成vue的打包.然后可以 用 npm 包 serve 启动静态文件服务 serve -l 5000.然后替换

1
2
// @resource     uiJs   https://raw.githubusercontent.com/jae-jae/Show-Site-All-UserJS/master/dist/ui.gf.js?_=1561104961645
// @resource ui https://raw.githubusercontent.com/jae-jae/Show-Site-All-UserJS/master/dist/ui.html?_=1561104961645

1
2
// @resource     uiJs   http://localhost:5000/ui.js?_=1561104961645
// @resource ui http://localhost:5000/ui.html?_=1561104961645

可以加个断点之类的.这部分是调试这个插件用vue写的可选插件的table组件. 可以用vsCode 调试npm npm run build --inspect-brk

  • 其他接口查询
    其他的获取网站到底有多少可用插件之类的是在项目里面的 userscript目录里面.然后这个我看是放在插件的主入口里面.感觉有点麻烦,没细看.有时间再慢慢看看.
发布

利用 github 的 Webhooks 同步发布到 greasyfork
初始化 import 脚本 https://greasyfork.org/en/import
2. 开启 webhook 并应用 https://greasyfork.org/en/users/webhook-info

按提示在 github 仓库的settings -> webhooks创建 hook, 每次仓库更新就会同步更新到 greasyfork

参考

使用 VueJS 开发油猴(TamperMonkey)脚本

Scramblies

  • 要求

    前者是否包含后者的每个字符,

  • 我的
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # 支持 集合运算,相减看是否包含 刷code war 题目 优化 看的
    from collections import Counter

    def scramble(s1, s2):
    # Counter basically creates a dictionary of counts and letters
    # Using set subtraction, we know that if anything is left over,
    # something exists in s2 that doesn't exist in s1
    return len(Counter(s2)- Counter(s1)) == 0

    print(scramble('rkqodlw', 'world'),)
  • 别人的
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #1
    def scramble(s1,s2):
    for c in set(s2):
    if s1.count(c) < s2.count(c):
    return False
    return True
    # 2 多用库
    from collections import Counter
    from operator import sub

    def scramble(s1,s2):
    return not sub(*map(Counter, (s2,s1)))
    # 2 特别的语法
    scramble=lambda a,b,c=__import__('collections').Counter:not c(b)-c(a)

setting up a Django project with React.

Django,React搭建前后台框架主要有以下思路(which are common to almost every web framework):

  1. React in its own “frontend” Django app: load a single HTML template and let React manage the frontend (difficulty: medium)

    • 作者推荐,
  2. Django REST as a standalone API + React as a standalone SPA (difficulty: hard, it involves JWT for authentication)
    demo都没怎么有设置权限,,作者有给提供连接,Django的登陆, drf的权限和认证,

    • 样例1

      • 这个通过CORS_ORIGIN_WHITELIST 这个设置可以控制权限?要不就跨域.
      • 感觉这个挺好的,然后集合了下面的用户请求,
    • 样例2

      这个是利用framework 发送用户名密码返回token然后存储,然后之后的请求都带上这个token

      1
      curl -X POST -d "username=admin&password=xxxx" http://localhost:8000/auth
  3. Mix and match: mini React apps inside Django templates (difficulty: simple)

    • 不推荐对新手

昨天12月2号电影中国首映。前一天买了票,然后在朋友圈宣传了一下。去看了之后,觉得还是没有失望。挺满足的。画质好,仔细想想音乐起到的作用也很大。
我是几个月前从网路上下载的资源看的第一遍,但是就觉得很合我胃口,然后按照习惯,查了半天相关资料,看消息说因为片源外泄,不准备在中国上映了,还挺失落。发朋友圈宣传并哀悼了一下,说很希望能在电影院再看一遍。然后竟然梦想成真。
故事还算讲得通,称为神作主要是觉得震惊,怎么画质这么好,影片里面的苹果手机是见过的最好看的样子。比真手机好看多了。音乐代入感很强。然后默默哀悼了一下,我最喜欢的宫崎骏爷爷做不错来这种画质。。。。但是后来看知乎推送,知道其实这种看着很真实的画面有部分是照相拍摄转换的。宫崎骏爷爷那可都是手绘的。看那篇知乎我还知道做一个严谨的动画,要几百个人做几年。。。。。这够开发一个操作系统了都。。做动画竟然这么难。

  1. 搭建git 服务器
    • 不想共享出去代码(这个念头其实最好不要觉得自己代码真有多大价值。。。我是有台阿里ECS服务器,想着实践下,宽带1M,上传贼拉快,下载就100多K)。其实很简单。参考搭建Git服务器
      1
      2
      3
      4
      5
      6
      7
      8
      9
       382  01/12/16 16:48:52 adduser git
      384 01/12/16 16:50:52 cd /home/git/
      388 01/12/16 16:51:05 mkdir wolife
      389 01/12/16 16:51:06 cd wolife/
      394 01/12/16 16:51:38 git init --bare wolife.git
      396 01/12/16 16:52:01 chown -R git:git wolife.git/
      397 01/12/16 16:52:07 vim /etc/passwd //这个是为了安全 设置除去远程登陆 。
      400 01/12/16 16:53:40 su - git //设置一下 ssh-keygen 在/home/git/.ssh/ 下 vim authorized_keys
      406 01/12/16 17:10:22 cd /home/git/wolife
  2. 本机eclipse egit 同步
    • Team -> share 然后做设置。
    • egit 一定要升级到最新版本,要不出一些莫名其妙的错误。
    • 主要是参考这个跟这个的配置做的,但是觉得有点老。。用来整理思路还是很好的
    • 设置忽略文件配置
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
       //编写.gitignore文件
      *.class
      *.a
      *.log
      .svn/
      work/
      config.json
      system.js
      classes/
      class/
      bin/
      //.gitignore为全局的方法
      在Git的命令行里输入: $ git config --global core.excludesfile ~/.gitignore_global 输入完成后,可打开.gitconfig文件,会发现里面自动添加了 [plain]
      [core]
      excludesfile = c:/Users/你的账户文件夹/.gitignore_global
  3. 使用Git Flow实现git最优开发实践
    感觉就是帮助用户简化git开发流。具体在连接有讲实践思路GIT分支管理是一门艺术

Paste_Image.png

TortoiseGit (海龟Git)是TortoiseSVN的Git版本

http://www.oschina.net/p/tortoisegit/